From b3f779a48a756f83051ca274da2a2f917df9e7c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 19 Aug 2021 20:28:37 -0700 Subject: Remove extjs path --- setup/package.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/package.sh b/setup/package.sh index bb890fbd0..e5f976b79 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -39,7 +39,6 @@ warn () { VERSION=$1 PLATFORM=${2:-all} -export EXTJS_PATH=$(cd ../..; pwd)/ext-6.2.0 PREREQ=true check_requirement () { -- cgit v1.2.3 From d47b07999d38881ec2a8fee3be6683d3e0a724d5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 Aug 2021 10:29:33 -0700 Subject: Improve Navtelecom support --- .../protocol/NavtelecomProtocolDecoder.java | 48 +++++++++++++++------- .../protocol/NavtelecomProtocolDecoderTest.java | 3 ++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 2362b1870..b2272a128 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -32,6 +32,23 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + 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 { @@ -45,24 +62,27 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // data checksum buf.readUnsignedByte(); // header checksum - String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + String type = buf.toString(buf.readerIndex(), 6, StandardCharsets.US_ASCII); - if (sentence.startsWith("*>S")) { + if (type.startsWith("*>S")) { - String data = "*FLEX")) { + + buf.skipBytes(6); + + ByteBuf payload = Unpooled.buffer(); + payload.writeByte(buf.readUnsignedByte()); // protocol + payload.writeByte(buf.readUnsignedByte()); // protocol version + payload.writeByte(buf.readUnsignedByte()); // struct version - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } + sendResponse(channel, remoteAddress, receiver, sender, payload); } diff --git a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java index 8b22c6e79..be51cb852 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class NavtelecomProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "404e544301000000000000001300f7fc2a3e464c4558b00a0a45fffe00000000000000")); + verifyNull(decoder, binary( + "404e544301000000000000001300cbc02a3e464c4558b00a0a45fffe300a0e08000000")); + } } -- cgit v1.2.3 From 2744b305b48d1d1215e326b3858a18f32d485eef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 Aug 2021 22:41:47 -0700 Subject: Implement MapTiler geocoder --- src/main/java/org/traccar/MainModule.java | 5 +- .../java/org/traccar/geocoder/JsonGeocoder.java | 4 +- .../org/traccar/geocoder/MapTilerGeocoder.java | 73 ++++++++++++++++++++++ .../java/org/traccar/geocoder/GeocoderTest.java | 9 +++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/geocoder/MapTilerGeocoder.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index e1a4d6b1c..80baebeee 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 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. @@ -40,6 +40,7 @@ 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; @@ -188,6 +189,8 @@ 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); } diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index 3cd5b596e..f20aa79d6 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -97,7 +97,9 @@ public abstract class JsonGeocoder implements Geocoder { } } - Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); + if (Main.getInjector() != null) { + 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 new file mode 100644 index 000000000..6b688a6e8 --- /dev/null +++ b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java @@ -0,0 +1,73 @@ +/* + * 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/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 5f1748984..380980d2b 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -101,4 +101,13 @@ public class GeocoderTest { String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("120 East 13th Street, New York, New York 10003, United States", address); } + + @Ignore + @Test + public void testMapTiler() { + Geocoder geocoder = new MapTilerGeocoder("mnbnwLErpdspq13f0kC6", 0, new AddressFormat()); + String address = geocoder.getAddress(40.733, -73.989, null); + assertEquals("East 13th Street, New York City, New York, United States", address); + } + } -- cgit v1.2.3 From e7b402ee1166a9c0610b45976da7a9528788628a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 Aug 2021 21:12:33 -0700 Subject: Remove Teltonika attributes --- .../java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 6ba183f9b..0cc2319a4 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -258,16 +258,6 @@ 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; -- cgit v1.2.3 From 0a98b2b5471526d9d166c4b81f1500fd1edb60df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 Aug 2021 21:55:09 -0700 Subject: Decode iStartek ignition --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index aae764993..b791e7bdd 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -168,8 +168,12 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), parser.nextInt()))); position.set(Position.KEY_STATUS, parser.nextHexInt()); - position.set(Position.KEY_INPUT, parser.nextHexInt()); - position.set(Position.KEY_OUTPUT, 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_POWER, parser.nextHexInt() * 0.01); position.set(Position.KEY_BATTERY, parser.nextHexInt() * 0.01); -- cgit v1.2.3 From 297e330ead69b92a4723369098e7c4dbf7aa5694 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Aug 2021 23:14:30 -0700 Subject: Implement orders functionality --- schema/changelog-4.15.xml | 66 ++++++++++++++++++++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/Context.java | 14 ++++- .../org/traccar/api/resource/OrderResource.java | 35 ++++++++++++ .../java/org/traccar/database/DataManager.java | 3 + .../java/org/traccar/database/OrderManager.java | 26 +++++++++ .../org/traccar/database/PermissionsManager.java | 9 ++- src/main/java/org/traccar/model/Order.java | 60 ++++++++++++++++++++ 8 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 schema/changelog-4.15.xml create mode 100644 src/main/java/org/traccar/api/resource/OrderResource.java create mode 100644 src/main/java/org/traccar/database/OrderManager.java create mode 100644 src/main/java/org/traccar/model/Order.java diff --git a/schema/changelog-4.15.xml b/schema/changelog-4.15.xml new file mode 100644 index 000000000..e8dd15bb5 --- /dev/null +++ b/schema/changelog-4.15.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index df54737a2..245367de3 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -28,5 +28,6 @@ + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index fe494dabf..aeba9c4c9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -38,6 +38,7 @@ 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; @@ -53,6 +54,7 @@ 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; @@ -235,6 +237,12 @@ public final class Context { return maintenancesManager; } + private static OrderManager orderManager; + + public static OrderManager getOrderManager() { + return orderManager; + } + private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -337,6 +345,8 @@ public final class Context { commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); + orderManager = new OrderManager(dataManager); + } private static void initEventsModule() { @@ -397,6 +407,8 @@ public final class Context { return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; + } else if (clazz.equals(Order.class)) { + return (BaseObjectManager) orderManager; } return null; } diff --git a/src/main/java/org/traccar/api/resource/OrderResource.java b/src/main/java/org/traccar/api/resource/OrderResource.java new file mode 100644 index 000000000..77608a508 --- /dev/null +++ b/src/main/java/org/traccar/api/resource/OrderResource.java @@ -0,0 +1,35 @@ +/* + * 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 { + + public OrderResource() { + super(Order.class); + } + +} diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index de6da8f23..00c802fde 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -41,6 +41,7 @@ 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; @@ -388,6 +389,8 @@ 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 new file mode 100644 index 000000000..c3253e52f --- /dev/null +++ b/src/main/java/org/traccar/database/OrderManager.java @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.database; + +import org.traccar.model.Order; + +public class OrderManager extends ExtendedObjectManager { + + public OrderManager(DataManager dataManager) { + super(dataManager, Order.class); + } + +} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index a27eac069..32464cf90 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 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -29,6 +29,7 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; +import org.traccar.model.Order; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; @@ -395,6 +396,8 @@ 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"); } @@ -454,6 +457,8 @@ 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(); @@ -469,6 +474,8 @@ 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/model/Order.java b/src/main/java/org/traccar/model/Order.java new file mode 100644 index 000000000..fe6d926b8 --- /dev/null +++ b/src/main/java/org/traccar/model/Order.java @@ -0,0 +1,60 @@ +/* + * 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; + } + +} -- cgit v1.2.3 From 707bdf44a32238a14fed324c12f69c343d3dd8c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 Aug 2021 23:13:30 -0700 Subject: Add modular response --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 281234ebb..a2944118a 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1131,6 +1131,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { + sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); + return decodeExtendedModular(buf, deviceSession); } else { -- cgit v1.2.3 From c56e307c9626d19b271ef04d852194a4e2069795 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 Aug 2021 21:19:50 -0700 Subject: Update response --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 37d7ae718..68da85067 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -71,7 +71,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { if (shortIndex) { buf.writeByte(1); } else { - buf.writeShort(1); + buf.writeShort(0); } buf.writeBytes(data); data.release(); -- cgit v1.2.3 From daa63a3aa7ae0c7092e24d0a536e78bdd785ae35 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Sep 2021 23:49:10 -0700 Subject: Fix response --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index a2944118a..3ffa873bd 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1131,7 +1131,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); + sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); return decodeExtendedModular(buf, deviceSession); -- cgit v1.2.3 From 5136e43a11c842bac982fd7c6e9a0d838251d3ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 5 Sep 2021 10:46:26 -0700 Subject: Persist sessions by default --- setup/default.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/default.xml b/setup/default.xml index 20bf515d2..b1ff04b9a 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,6 +12,7 @@ 8082 ./web + true false google -- cgit v1.2.3 From e3c8872e2dcf0bd9affb138a8f827bfa7d42d6ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Sep 2021 23:11:28 -0700 Subject: Add test case --- src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index e85672326..ace65ece6 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -15,6 +15,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { "&&:23,860262050015424,129,OKA2"), Position.KEY_RESULT, "129,OK"); + verifyNull(decoder, text( + "&&X152,861157040151686,000,18,,210907163833,A,10.232715,-67.880423,11,1.4,0,275,437,34804,734|2|3EE4|00579406,28,00000015,00,00,0000|017D|0000|0000,1,010000,,9A")); + verifyPosition(decoder, text( "&&o125,861157040554384,000,0,,210702235150,A,27.263505,153.037061,11,1.2,0,0,31,5125,505|1|7032|8C89802,20,0000002D,00,00,01E2|019DF0")); -- cgit v1.2.3 From f7b98d5ae86029361629c55d5b7ffc7dcdd0ed99 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Sep 2021 22:26:27 -0700 Subject: Handle trailing comma --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index b791e7bdd..65d295dc3 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -77,7 +77,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .text(",") .number("d,") // extended .expression("([^,]+)?,") // fuel - .expression("([^,]+)?") // temperature + .expression("([^,]+)?,?") // temperature .groupEnd("?") .groupEnd("?") .compile(); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index ace65ece6..1fbe71988 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -15,7 +15,7 @@ public class StartekProtocolDecoderTest extends ProtocolTest { "&&:23,860262050015424,129,OKA2"), Position.KEY_RESULT, "129,OK"); - verifyNull(decoder, text( + verifyPosition(decoder, text( "&&X152,861157040151686,000,18,,210907163833,A,10.232715,-67.880423,11,1.4,0,275,437,34804,734|2|3EE4|00579406,28,00000015,00,00,0000|017D|0000|0000,1,010000,,9A")); verifyPosition(decoder, text( -- cgit v1.2.3 From 2a5bf04563ecc8b09f07a0007335bbd111f9c0a2 Mon Sep 17 00:00:00 2001 From: soshial Date: Fri, 10 Sep 2021 09:22:55 +0200 Subject: add support for relative filtering --- setup/default.xml | 13 ++++ src/main/java/org/traccar/config/Keys.java | 16 ++++- .../java/org/traccar/database/DataManager.java | 36 ++++++++++ .../java/org/traccar/handler/FilterHandler.java | 79 ++++++++++++++++------ 4 files changed, 120 insertions(+), 24 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 0564182c7..e798fcf88 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -22,6 +22,7 @@ true 86400 + false true true @@ -48,6 +49,18 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 + + + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND NOT fixTime lt :time LIMIT 1 ORDER BY fixTime DESC + + + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time LIMIT 1 ORDER BY fixTime ASC + + SELECT tc_positions.* FROM tc_positions INNER JOIN tc_devices ON tc_positions.id = tc_devices.positionid; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6d2296fb1..f7d61a993 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -887,8 +887,19 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * 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. + * If FALSE, then filter compares duplicates, distance or period only with the last received location. + * Server expects all locations to come sequentially. + * + * If TRUE, then filter compares duplicates, distance or period with Position's fixTime strictly before and after. + * Server expects locations to come at random order, since tracking device might go offline. + */ + public static final ConfigKey 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. */ public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( "filter.skipLimit", @@ -896,6 +907,7 @@ 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 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 15137ad91..3f702f78a 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -328,6 +328,42 @@ public class DataManager { .executeQuery(Position.class); } + public Position getPositionByTime(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPositionByTime")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + + public Position getPrevPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrevPosition")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + + public Position getNextPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectNextPosition")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + public void updateLatestPosition(Position position) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.updateLatestPosition")) .setDate("now", new Date()) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 7cd9153c1..817d6c8ba 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -25,6 +25,9 @@ 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 { @@ -40,6 +43,7 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long filterMinPeriod; + private boolean filterRelative; private long skipLimit; private boolean skipAttributes; @@ -54,14 +58,15 @@ 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) { @@ -144,20 +149,13 @@ public class FilterHandler extends BaseDataHandler { StringBuilder filterType = new StringBuilder(); - Position last = null; - if (Context.getIdentityManager() != null) { - last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - } - + // general filtering 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 "); } @@ -167,19 +165,56 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - 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 (filterRelative) { + try { + if (filterStatic(position) && !skipAttributes(position)) { + filterType.append("Static "); + } + Date newfixTime = position.getFixTime(); + Position duplicate = Context.getDataManager().getPositionByTime(position.getDeviceId(), newfixTime); + if (filterDuplicate(position, duplicate) && !skipLimit(position, duplicate) + && !skipAttributes(position)) { + filterType.append("Duplicate "); + } + + Position previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newfixTime); + Position next = Context.getDataManager().getNextPosition(position.getDeviceId(), newfixTime); + if ((filterDistance(position, previous) || filterDistance(next, position)) + && !skipAttributes(position)) { + filterType.append("Distance "); + } + if (filterMaxSpeed(position, previous) || filterMaxSpeed(next, position)) { + filterType.append("MaxSpeed "); + } + if (filterMinPeriod(position, previous) || filterMinPeriod(next, position)) { + filterType.append("MinPeriod "); + } + } catch (SQLException e) { + LOGGER.warn("Error filtering position", e); + } + } else { + Position last = null; + if (Context.getIdentityManager() != null) { + last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + } + + if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Duplicate "); + } + 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) { StringBuilder message = new StringBuilder(); -- cgit v1.2.3 From f089fe842ad3fb69550bcb65fee2f0377cc7bab0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Sep 2021 18:57:47 -0700 Subject: Fix response --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index b2272a128..0e9685356 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -78,6 +78,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(6); ByteBuf payload = Unpooled.buffer(); + payload.writeCharSequence("* Date: Sat, 11 Sep 2021 19:08:26 -0700 Subject: Add photo response --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 68da85067..98ab8677f 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -59,6 +59,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { 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; @@ -176,7 +177,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO) { sendGeneralResponse(channel, remoteAddress, id, type, index); -- cgit v1.2.3 From 55b0a40e51e0bee5d37f0f3d34b6f1dd287973f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Sep 2021 19:25:07 -0700 Subject: Decode Portman ignition --- src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java index ebb93abd6..e1847a2b2 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java @@ -80,7 +80,15 @@ 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()); - position.set(Position.KEY_EVENT, parser.nextInt()); + + 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_SATELLITES, parser.nextInt()); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_RSSI, parser.nextInt()); -- cgit v1.2.3 From d9ad81991da306dcae35bb6b7ba7f90c6d6b8725 Mon Sep 17 00:00:00 2001 From: soshial Date: Sun, 12 Sep 2021 05:23:12 +0200 Subject: filtering optimizations --- setup/default.xml | 4 +- src/main/java/org/traccar/config/Keys.java | 7 ++- .../java/org/traccar/handler/FilterHandler.java | 62 +++++++++------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index e798fcf88..54677d845 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -54,11 +54,11 @@ - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND NOT fixTime lt :time LIMIT 1 ORDER BY fixTime DESC + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time LIMIT 1 ORDER BY fixTime ASC + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time ORDER BY fixTime ASC LIMIT 1 diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f7d61a993..c6a202d2f 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -872,8 +872,11 @@ 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 they're - * marked as valid. 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 Position + * appears valid or if Position `speed` field reported by the device is also within limits. Calculates speed from + * the distance to the previous position and the elapsed time. + * + * Tip: Shouldn't be too low. Start testing with values at about 25000. */ public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( "filter.maxSpeed", diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 817d6c8ba..16e5ae2da 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -146,6 +146,9 @@ public class FilterHandler extends BaseDataHandler { } private boolean filter(Position position) { + if (skipAttributes(position)) { + return false; + } StringBuilder filterType = new StringBuilder(); @@ -165,58 +168,43 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - if (filterRelative) { - try { - if (filterStatic(position) && !skipAttributes(position)) { - filterType.append("Static "); - } - - Date newfixTime = position.getFixTime(); - Position duplicate = Context.getDataManager().getPositionByTime(position.getDeviceId(), newfixTime); - if (filterDuplicate(position, duplicate) && !skipLimit(position, duplicate) - && !skipAttributes(position)) { - filterType.append("Duplicate "); - } + if (filterStatic(position)) { + filterType.append("Static "); + } - Position previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newfixTime); - Position next = Context.getDataManager().getNextPosition(position.getDeviceId(), newfixTime); - if ((filterDistance(position, previous) || filterDistance(next, position)) - && !skipAttributes(position)) { - filterType.append("Distance "); + // relative filtering + if (filterDuplicate || filterDistance != 0 || filterMaxSpeed != 0 || filterMinPeriod != 0) { + Position previous = null; + if (filterRelative) { + try { + Date newFixTime = position.getFixTime(); + previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newFixTime); + } catch (SQLException e) { + LOGGER.warn("Error filtering position", e); } - if (filterMaxSpeed(position, previous) || filterMaxSpeed(next, position)) { - filterType.append("MaxSpeed "); + } else { + if (Context.getIdentityManager() != null) { + previous = Context.getIdentityManager().getLastPosition(position.getDeviceId()); } - if (filterMinPeriod(position, previous) || filterMinPeriod(next, position)) { - filterType.append("MinPeriod "); - } - } catch (SQLException e) { - LOGGER.warn("Error filtering position", e); } - } else { - Position last = null; - if (Context.getIdentityManager() != null) { - last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + if (skipLimit(position, previous)) { + return false; } - - if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + if (filterDuplicate(position, previous)) { filterType.append("Duplicate "); } - if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Static "); - } - if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + if (filterDistance(position, previous)) { filterType.append("Distance "); } - if (filterMaxSpeed(position, last)) { + if (filterMaxSpeed(position, previous)) { filterType.append("MaxSpeed "); } - if (filterMinPeriod(position, last)) { + if (filterMinPeriod(position, previous)) { filterType.append("MinPeriod "); } } - if (filterType.length() > 0) { + if (filterType.length() > 0) { StringBuilder message = new StringBuilder(); message.append("Position filtered by "); message.append(filterType.toString()); -- cgit v1.2.3 From 961570af087c2b01935542f78a851a9908ccb430 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Sep 2021 22:20:12 -0700 Subject: Add Mictrack B2316 protocol --- setup/default.xml | 1 + .../java/org/traccar/protocol/B2316Protocol.java | 37 +++++ .../org/traccar/protocol/B2316ProtocolDecoder.java | 162 +++++++++++++++++++++ .../traccar/protocol/B2316ProtocolDecoderTest.java | 18 +++ 4 files changed, 218 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/B2316Protocol.java create mode 100644 src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index b1ff04b9a..f9529d465 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -295,5 +295,6 @@ 5227 5228 5229 + 5230 diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java new file mode 100644 index 000000000..7f08870ce --- /dev/null +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -0,0 +1,37 @@ +/* + * 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 new file mode 100644 index 000000000..854107a20 --- /dev/null +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -0,0 +1,162 @@ +/* + * 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 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/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java new file mode 100644 index 000000000..6b9c71b0e --- /dev/null +++ b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class B2316ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new B2316ProtocolDecoder(null); + + verifyPositions(decoder, false, text( + "{\"imei\":\"866349041783600\",\"data\":[{\"tm\":1631162952,\"wn\":7},{\"tm\":1631158729,\"ic\":\"89883030000059398609\",\"ve\":\"B2316.TAU.U.TH01\"},{\"tm\":1631158805,\"te\":\"312,363\",\"st\":0,\"ba\":3,\"sn\":80},{\"tm\":1631158829,\"ci\":\"505,1,8218,133179149,-108\"},{\"tm\":1631162956,\"wi\":\"101331c17f4f,-74;f46bef7953bb,-81;b09575cff1c8,-86;e2b9e5d61a7a,-88;b0ee7b4dee2f,-88;e0b9e5d61a77,-89;f66bef7953b9,-89;\",\"te\":\"335,366\",\"hr\":58,\"bp\":\"113,73\",\"st\":0,\"ba\":3,\"sn\":60},{\"tm\":1631162968,\"ci\":\"505,1,8218,133179149,-105\"}]}")); + + } + +} -- cgit v1.2.3 From 7a3b106dfc28a6254825b8d664db8181f4bd19f1 Mon Sep 17 00:00:00 2001 From: soshial Date: Sun, 12 Sep 2021 09:31:38 +0200 Subject: improve naming and comments --- setup/default.xml | 7 +---- src/main/java/org/traccar/config/Keys.java | 9 +++--- .../java/org/traccar/database/DataManager.java | 16 ++-------- .../java/org/traccar/handler/FilterHandler.java | 35 ++++++++++++++-------- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 54677d845..7ed3e35b2 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -22,7 +22,6 @@ true 86400 - false true true @@ -53,14 +52,10 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 - + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time ORDER BY fixTime ASC LIMIT 1 - - SELECT tc_positions.* FROM tc_positions INNER JOIN tc_devices ON tc_positions.id = tc_devices.positionid; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index c6a202d2f..a77204175 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -890,11 +890,12 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * If FALSE, then filter compares duplicates, distance or period only with the last received location. - * Server expects all locations to come sequentially. + * 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, then filter compares duplicates, distance or period with Position's fixTime strictly before and after. - * Server expects locations to come at random order, since tracking device might go offline. + * 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 FILTER_RELATIVE = new ConfigKey<>( "filter.relative", diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 3f702f78a..d8401774e 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -340,20 +340,8 @@ public class DataManager { } } - public Position getPrevPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrevPosition")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } - } - - public Position getNextPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectNextPosition")) + public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) .setDate("time", date) .executeQuery(Position.class); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 16e5ae2da..5287a7639 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -146,6 +146,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filter(Position position) { + if (skipAttributes(position)) { return false; } @@ -173,43 +174,44 @@ public class FilterHandler extends BaseDataHandler { } // relative filtering - if (filterDuplicate || filterDistance != 0 || filterMaxSpeed != 0 || filterMinPeriod != 0) { - Position previous = null; + long deviceId = position.getDeviceId(); + if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { + Position preceding = null; if (filterRelative) { try { Date newFixTime = position.getFixTime(); - previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newFixTime); + preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); } catch (SQLException e) { - LOGGER.warn("Error filtering position", e); + LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); + preceding = getLastReceivedPosition(deviceId); } } else { - if (Context.getIdentityManager() != null) { - previous = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - } + preceding = getLastReceivedPosition(deviceId); } - if (skipLimit(position, previous)) { + if (skipLimit(position, preceding)) { return false; } - if (filterDuplicate(position, previous)) { + if (filterDuplicate(position, preceding)) { filterType.append("Duplicate "); } - if (filterDistance(position, previous)) { + if (filterDistance(position, preceding)) { filterType.append("Distance "); } - if (filterMaxSpeed(position, previous)) { + if (filterMaxSpeed(position, preceding)) { filterType.append("MaxSpeed "); } - if (filterMinPeriod(position, previous)) { + if (filterMinPeriod(position, preceding)) { filterType.append("MinPeriod "); } } if (filterType.length() > 0) { + StringBuilder message = new StringBuilder(); message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); + message.append(Context.getIdentityManager().getById(deviceId).getUniqueId()); LOGGER.info(message.toString()); return true; @@ -218,6 +220,13 @@ 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)) { -- cgit v1.2.3 From fd91d6bbb189b091799708a4d3f4e9d9ca114763 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 13 Sep 2021 08:21:35 +0200 Subject: remove comments --- setup/default.xml | 4 ---- src/main/java/org/traccar/database/DataManager.java | 12 ------------ src/main/java/org/traccar/handler/FilterHandler.java | 2 -- 3 files changed, 18 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 7ed3e35b2..419eaef45 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -48,10 +48,6 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index d8401774e..15c67cb74 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -328,18 +328,6 @@ public class DataManager { .executeQuery(Position.class); } - public Position getPositionByTime(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPositionByTime")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } - } - public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 5287a7639..6331ff773 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -153,7 +153,6 @@ public class FilterHandler extends BaseDataHandler { StringBuilder filterType = new StringBuilder(); - // general filtering if (filterInvalid(position)) { filterType.append("Invalid "); } @@ -173,7 +172,6 @@ public class FilterHandler extends BaseDataHandler { filterType.append("Static "); } - // relative filtering long deviceId = position.getDeviceId(); if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; -- cgit v1.2.3 From a6ccfd679686cfb62f8390334229ba7fdf92eb42 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 13 Sep 2021 21:42:56 +0200 Subject: fix SQL syntax in XML --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 419eaef45..e427d05e5 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -49,7 +49,7 @@ - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime <= :time ORDER BY fixTime DESC LIMIT 1 -- cgit v1.2.3 From ae00c6a6741497036bf7257439e4b9aca41cae40 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Sep 2021 22:53:52 -0700 Subject: Decode LLS groups --- src/main/java/org/traccar/protocol/BceProtocolDecoder.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index a26b8e8e6..c1a69981d 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -177,10 +177,16 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShortLE(); // dallas humidity } if (BitUtil.check(mask, 9)) { - buf.skipBytes(6); // lls group 1 + position.set("fuel1", buf.readUnsignedShortLE()); + position.set("fuelTemp1", (int) buf.readByte()); + position.set("fuel2", buf.readUnsignedShortLE()); + position.set("fuelTemp2", (int) buf.readByte()); } if (BitUtil.check(mask, 10)) { - buf.skipBytes(6); // lls group 2 + position.set("fuel3", buf.readUnsignedShortLE()); + position.set("fuelTemp3", (int) buf.readByte()); + position.set("fuel4", buf.readUnsignedShortLE()); + position.set("fuelTemp4", (int) buf.readByte()); } if (BitUtil.check(mask, 11)) { buf.skipBytes(21); // j1979 group 1 -- cgit v1.2.3 From 1a40dfa1fc286f03ab4ce4468984a226e68afe0c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Sep 2021 23:14:56 -0700 Subject: Decode additional data --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 98ab8677f..cd7273f6b 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -333,6 +333,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); } break; + case 0xAC: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + break; case 0xD0: long userStatus = buf.readUnsignedInt(); if (BitUtil.check(userStatus, 3)) { @@ -390,6 +393,16 @@ 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.01); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + break; default: break; } -- cgit v1.2.3 From 4fb9eba760b571d86fff4c1b0f645a7c6d4fbe16 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 15 Sep 2021 23:13:16 -0700 Subject: Update when geofences change --- src/main/java/org/traccar/MainModule.java | 11 +++++++++-- .../java/org/traccar/handler/events/GeofenceEventHandler.java | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 80baebeee..11100f66e 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -23,6 +23,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; import org.traccar.database.CalendarManager; +import org.traccar.database.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; @@ -105,6 +106,11 @@ public class MainModule extends AbstractModule { return Context.getIdentityManager(); } + @Provides + public static ConnectionManager provideConnectionManager() { + return Context.getConnectionManager(); + } + @Provides public static Client provideClient() { return Context.getClient(); @@ -393,8 +399,9 @@ public class MainModule extends AbstractModule { @Singleton @Provides public static GeofenceEventHandler provideGeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { - return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager); + IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, + ConnectionManager connectionManager) { + return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager, connectionManager); } @Singleton diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index f4807e56b..dae0c891f 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 - 2019 Anton Tananaev (anton@traccar.org) + * 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. @@ -22,6 +22,7 @@ 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; @@ -35,12 +36,15 @@ 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) { + IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, + ConnectionManager connectionManager) { this.identityManager = identityManager; this.geofenceManager = geofenceManager; this.calendarManager = calendarManager; + this.connectionManager = connectionManager; } @Override @@ -63,6 +67,9 @@ public class GeofenceEventHandler extends BaseEventHandler { oldGeofences.removeAll(currentGeofences); device.setGeofenceIds(currentGeofences); + if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { + connectionManager.updateDevice(device); + } Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { -- cgit v1.2.3 From 2e056dcecffcb139445599242d18f9d22a849e40 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Sep 2021 21:28:32 -0700 Subject: Fix voltage decoding --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cd7273f6b..4d77d554e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -399,8 +399,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { break; case 0xEE: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + 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: -- cgit v1.2.3 From ae2e61d4e0a31deb5952dfd209026368cc5708dd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Sep 2021 22:17:06 -0700 Subject: Support G28 4G protocol --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 3ffa873bd..b313802b3 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -78,8 +78,11 @@ 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_AZ735_GPS = 0x32; - public static final int MSG_AZ735_ALARM = 0x33; + 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_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -120,9 +123,11 @@ 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_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,9 +147,11 @@ 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_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: @@ -163,6 +170,7 @@ 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; @@ -690,9 +698,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_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { - boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3; + boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -703,7 +711,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mcc = buf.readUnsignedShort(); int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - for (int i = 0; i < 7; i++) { + + int cellCount = type == MSG_WIFI_5 ? 6 : 7; + for (int i = 0; i < cellCount; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); int rssi = -buf.readUnsignedByte(); -- cgit v1.2.3 From bbd1eeae922339316914ea0c3debead9ade784ae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Sep 2021 11:09:23 -0700 Subject: Remove order unique constraint --- schema/changelog-4.15.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/schema/changelog-4.15.xml b/schema/changelog-4.15.xml index e8dd15bb5..57b9b341a 100644 --- a/schema/changelog-4.15.xml +++ b/schema/changelog-4.15.xml @@ -23,8 +23,6 @@ - - -- cgit v1.2.3 From c2ee0f4d9688de777b3f7cdf12ae486e22ae47ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Sep 2021 12:07:50 -0700 Subject: Increase frame limit --- src/main/java/org/traccar/protocol/NavtelecomProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 29ad62e48..24bfbf895 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -28,7 +28,7 @@ public class NavtelecomProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 12, 2, 2, 0, true)); + pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 65535, 12, 2, 2, 0, true)); pipeline.addLast(new NavtelecomProtocolDecoder(NavtelecomProtocol.this)); } }); -- cgit v1.2.3 From c345945c36b4c93f2f436cf61f89495577d072ea Mon Sep 17 00:00:00 2001 From: soshial Date: Sat, 18 Sep 2021 21:15:24 +0200 Subject: improve SQL query --- src/main/java/org/traccar/database/DataManager.java | 9 ++------- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 15c67cb74..75ec70ea7 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -329,15 +329,10 @@ public class DataManager { } public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) + return QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } + .executeQuerySingle(Position.class); } public void updateLatestPosition(Position position) throws SQLException { diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 6331ff773..19d72d8a1 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -74,7 +74,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filterDuplicate(Position position, Position last) { - if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { + if (filterDuplicate && last != null && position.getFixTime().getTime() == last.getFixTime().getTime()) { for (String key : position.getAttributes().keySet()) { if (!last.getAttributes().containsKey(key)) { return false; -- cgit v1.2.3 From abf9f5f445bd2d460bf541ea0edb1bce339d2180 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Sep 2021 22:49:16 -0700 Subject: More Starlink parameters --- .../traccar/protocol/StarLinkProtocolDecoder.java | 33 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 82f0e4061..7a6b6f4fe 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -150,9 +150,21 @@ 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)); @@ -166,6 +178,9 @@ 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; @@ -185,11 +200,15 @@ 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; @@ -217,6 +236,9 @@ 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]); @@ -241,18 +263,23 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { break; case "#IGN#": case "#IGNL#": - position.set(Position.KEY_IGNITION, data[i].equals("1")); - break; case "#ENG#": - position.set("engine", data[i].equals("1")); + position.set(Position.KEY_IGNITION, Integer.parseInt(data[i]) > 0); 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; -- cgit v1.2.3 From 0410bce8df4f66aec23232caf03100a36527d15b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Sep 2021 22:08:20 -0700 Subject: Remove incorrect alarms --- src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index 2ca71a1ae..0284ff6c7 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -140,8 +140,6 @@ 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": @@ -152,10 +150,6 @@ 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": @@ -170,6 +164,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_FOOT_BRAKE; case "DTC": return Position.ALARM_FAULT; + case "tracker": default: return null; } -- cgit v1.2.3 From 49a5ac1259f299615e56d5d8e733234a4d7364bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Sep 2021 22:21:43 -0700 Subject: GPS rollover fix for MXT --- src/main/java/org/traccar/protocol/MxtProtocolDecoder.java | 6 +++++- src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index 7bde85f87..c36be9cbf 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 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -97,6 +97,10 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { long date = buf.readUnsignedIntLE(); long days = BitUtil.from(date, 6 + 6 + 5); + if (days < 7 * 1024) { + 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/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java index 71ad22a96..301b6102b 100644 --- a/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MxtProtocolDecoderTest extends ProtocolTest { var decoder = new MxtProtocolDecoder(null); + verifyPosition(decoder, binary( + "01a631a7627b00087dc41c40850006aab70affecdf23fd32200080000600000000000000000000001b2ff03b1bb9c4c60214f40100050000006c2d0000f427600051051101de0704")); + verifyPosition(decoder, binary( "01a631144c7e0008643ad2f456fb2d49747cfe4cbe0ffd002008800000001021000fd43d3f1403000000ff300000f42760001031102445a81fda04")); -- cgit v1.2.3 From fd2d0d9795f12776ba7286ba7a4ff346b335be2f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Sep 2021 22:37:59 -0700 Subject: Fix tests --- src/main/java/org/traccar/protocol/MxtProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index c36be9cbf..379b610e1 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java @@ -97,7 +97,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { long date = buf.readUnsignedIntLE(); long days = BitUtil.from(date, 6 + 6 + 5); - if (days < 7 * 1024) { + if (days < 7 * 780) { days += 7 * 1024; } -- cgit v1.2.3 From 538e1b1dd83d4c2d45da6ed9b7e00ec7eeeba061 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Sep 2021 23:20:33 -0700 Subject: Support Suntech bluetooth (BLE) --- .../traccar/protocol/SuntechProtocolDecoder.java | 111 +++++++++++++-------- .../protocol/SuntechProtocolDecoderTest.java | 6 ++ 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index d8710a899..cf40e1e95 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 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. @@ -34,6 +34,7 @@ import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Date; import java.util.TimeZone; public class SuntechProtocolDecoder extends BaseProtocolDecoder { @@ -448,7 +449,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String type = values[index++]; - if (!type.equals("STT") && !type.equals("ALT")) { + if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE")) { return null; } @@ -462,6 +463,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_TYPE, type); int mask = Integer.parseInt(values[index++], 16); + if (type.equals("BLE")) { + mask = 0b1100000110110; + } if (BitUtil.check(mask, 1)) { index += 1; // model @@ -510,63 +514,84 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(Double.parseDouble(values[index++])); } - if (BitUtil.check(mask, 13)) { - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - } + if (type.equals("BLE")) { - if (BitUtil.check(mask, 14)) { - position.setCourse(Double.parseDouble(values[index++])); - } + position.setValid(true); - if (BitUtil.check(mask, 15)) { - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); - } + int count = Integer.parseInt(values[index++]); + index += 1; - if (BitUtil.check(mask, 16)) { - position.setValid(values[index++].equals("1")); - } + 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, 17)) { - position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); - } + } else { - if (BitUtil.check(mask, 18)) { - position.set(Position.KEY_OUTPUT, Integer.parseInt(values[index++])); - } + if (BitUtil.check(mask, 13)) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + } - if (type.equals("ALT")) { - if (BitUtil.check(mask, 19)) { - position.set("alertId", values[index++]); + if (BitUtil.check(mask, 14)) { + position.setCourse(Double.parseDouble(values[index++])); } - if (BitUtil.check(mask, 20)) { - position.set("alertModifier", values[index++]); + + if (BitUtil.check(mask, 15)) { + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); } - if (BitUtil.check(mask, 21)) { - position.set("alertData", values[index++]); + + if (BitUtil.check(mask, 16)) { + position.setValid(values[index++].equals("1")); } - } else { - if (BitUtil.check(mask, 19)) { - position.set("mode", Integer.parseInt(values[index++])); + + if (BitUtil.check(mask, 17)) { + position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); } - if (BitUtil.check(mask, 20)) { - position.set("reason", Integer.parseInt(values[index++])); + + if (BitUtil.check(mask, 18)) { + position.set(Position.KEY_OUTPUT, Integer.parseInt(values[index++])); } - if (BitUtil.check(mask, 21)) { - position.set(Position.KEY_INDEX, 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, 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/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 8cc4148f0..7f0700728 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -82,6 +82,12 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = new SuntechProtocolDecoder(null); + verifyPosition(decoder, buffer( + "BLE;0820012345;001FFF;82;1.0.0;20191203;17:00:51;+32.691615;-117.297160;2;2;-32;-100;33;AABBCCDDEEFF;12;18;52;1;-44;44;112233445566;32;69;101")); + + verifyNull(decoder, buffer( + "BSA;0820012345;001FFF;82;1.0.0;1;20191203;17:00:51;+32.691615;-117.297160;1;-55;68:11:6A:FD:1A:A7;6AA5;1DE8")); + verifyAttribute(decoder, buffer( "ST300UEX;511331307;45;311;20210420;12:41:01;12361;-01.280825;-047.931773;000.000;000.00;16;1;0;12.54;000000;23;GTSL|6|1|0|9255143|2|;6F;000276;0.0;1;00000000000000;0"), Position.KEY_DRIVER_UNIQUE_ID, "9255143"); -- cgit v1.2.3 From de76b91f467c2c4d1e393903ab3e3ae6c6167a5a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Sep 2021 23:21:50 -0700 Subject: Remove unused import --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index cf40e1e95..bee21982e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -34,7 +34,6 @@ import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; import java.util.TimeZone; public class SuntechProtocolDecoder extends BaseProtocolDecoder { -- cgit v1.2.3 From 63b97670ddbcd1a528e498d0c743f480c09c91ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Sep 2021 16:32:17 -0700 Subject: Support Yabby Edge forwarder --- .../traccar/protocol/DmtHttpProtocolDecoder.java | 57 ++++++++++++++++++++-- .../protocol/DmtHttpProtocolDecoderTest.java | 3 ++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 987361baf..ebf9a006c 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 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 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. @@ -32,7 +32,11 @@ 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; @@ -51,12 +55,25 @@ 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 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; } @@ -126,8 +143,42 @@ 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()); + + position.setValid(true); + position.setTime(new Date(OffsetDateTime.parse(root.getString("date")).toInstant().toEpochMilli())); + position.setLatitude(root.getJsonNumber("lat").doubleValue()); + position.setLongitude(root.getJsonNumber("lng").doubleValue()); + position.setAccuracy(root.getJsonNumber("posAcc").doubleValue()); + + position.set(Position.KEY_INDEX, root.getInt("sqn")); + position.set(Position.KEY_EVENT, root.getInt("reason")); + + 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")); + } + + position.set(Position.KEY_INPUT, root.getInt("inputs")); + position.set(Position.KEY_OUTPUT, root.getInt("outputs")); + position.set(Position.KEY_STATUS, root.getInt("status")); + + return position; + } + } diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index 634e37b89..d0143ac97 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { var decoder = new DmtHttpProtocolDecoder(null); + verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("{ \"date\": \"2021-04-20T11:10:03.702659861Z\", \"device\":{ \"sn\": \"0016C001F000ABEC\", \"prod\": 0.2, \"rev\": 0.3, \"fw\": \"1.1\", \"module\": \"LR 34.3.3\", \"iccid\": \"89610180000000000000\", \"imei\": \"354043000000000\" }, \"sqn\": 347263802, \"reason\":3, \"lat\": 1.1, \"lng\": 2.2, \"posAcc\": 30.1, \"posInfo\":{ \"HDOP\": 0.1, \"PDOP\": 0.2, \"GDOP\": 0.3, \"BSat\":1, \"GSat\":2, \"Src\":2 }, \"analogues\":[{ \"id\":1, \"val\": 300 },{ \"id\":2, \"val\": 500} ], \"inputs\": 5001, \"outputs\":0, \"status\": 17, \"counters\":[{ \"id\": 11, \"val\": 43 },{ \"id\": 23, \"val\": 8800} ], \"lora\":{ \"dev_id\": \"yabby-abec\", \"app_id\": \"digital-matter\", \"dev_addr\": \"260B567A\", \"gw\": [ { \"id\": \"dm-sentrius\", \"snr\": 10, \"rssi\": -36 } ] }}"))); + verifyPositions(decoder, request(HttpMethod.POST, "/", buffer("{\"SerNo\":131693,\"IMEI\":\"356692063643328\",\"ICCID\":\"8944538523010771676\",\"ProdId\":33,\"FW\":\"33.4.1.27\",\"Records\":[{\"SeqNo\":125,\"Reason\":11,\"DateUTC\":\"2017-05-11 05:58:44\",\"Fields\":[{\"GpsUTC\":\"2017-05-08 18:04:57\",\"Lat\":43.7370138,\"Long\":-79.3462607,\"Alt\":197,\"Spd\":0,\"SpdAcc\":13,\"Head\":66,\"PDOP\":18,\"PosAcc\":37,\"GpsStat\":7,\"FType\":0},{\"DIn\":2,\"DOut\":0,\"DevStat\":2,\"FType\":2},{\"AnalogueData\":{\"1\":14641,\"3\":2484,\"4\":26,\"5\":10868},\"FType\":6},{\"AnalogueData\":{\"11\":34,\"12\":0,\"13\":309,\"14\":9921,\"15\":3},\"FType\":7}]},{\"SeqNo\":128,\"Reason\":11,\"DateUTC\":\"2017-05-11 17:59:45\",\"Fields\":[{\"GpsUTC\":\"2017-05-08 18:04:57\",\"Lat\":43.7370138,\"Long\":-79.3462607,\"Alt\":197,\"Spd\":0,\"SpdAcc\":13,\"Head\":66,\"PDOP\":18,\"PosAcc\":37,\"GpsStat\":7,\"FType\":0},{\"DIn\":2,\"DOut\":0,\"DevStat\":2,\"FType\":2},{\"AnalogueData\":{\"1\":14607,\"3\":2752,\"4\":26,\"5\":11062},\"FType\":6},{\"AnalogueData\":{\"11\":34,\"12\":1,\"13\":325,\"14\":10881,\"15\":3},\"FType\":7}]},{\"SeqNo\":130,\"Reason\":9,\"DateUTC\":\"2017-05-11 19:30:03\",\"Fields\":[{\"GpsUTC\":\"2017-05-08 18:04:57\",\"Lat\":43.7370138,\"Long\":-79.3462607,\"Alt\":197,\"Spd\":0,\"SpdAcc\":13,\"Head\":66,\"PDOP\":18,\"PosAcc\":37,\"GpsStat\":3,\"FType\":0},{\"DIn\":6,\"DOut\":0,\"DevStat\":2,\"FType\":2},{\"AnalogueData\":{\"1\":14599,\"3\":2731,\"4\":27,\"5\":10965},\"FType\":6},{\"AnalogueData\":{\"11\":34,\"12\":2,\"13\":329,\"14\":11121,\"15\":3},\"FType\":7}]},{\"SeqNo\":131,\"Reason\":11,\"DateUTC\":\"2017-05-11 19:32:03\",\"Fields\":[{\"GpsUTC\":\"2017-05-08 18:04:57\",\"Lat\":43.7370138,\"Long\":-79.3462607,\"Alt\":197,\"Spd\":0,\"SpdAcc\":13,\"Head\":66,\"PDOP\":18,\"PosAcc\":37,\"GpsStat\":7,\"FType\":0},{\"DIn\":6,\"DOut\":0,\"DevStat\":2,\"FType\":2},{\"AnalogueData\":{\"1\":14403,\"3\":2783,\"4\":27,\"5\":10965},\"FType\":6},{\"AnalogueData\":{\"11\":34,\"12\":2,\"13\":330,\"14\":11181,\"15\":3},\"FType\":7}]},{\"SeqNo\":133,\"Reason\":11,\"DateUTC\":\"2017-05-11 19:36:15\",\"Fields\":[{\"GpsUTC\":\"2017-05-08 18:04:57\",\"Lat\":43.7370138,\"Long\":-79.3462607,\"Alt\":197,\"Spd\":0,\"SpdAcc\":13,\"Head\":66,\"PDOP\":18,\"PosAcc\":37,\"GpsStat\":7,\"FType\":0},{\"DIn\":6,\"DOut\":0,\"DevStat\":2,\"FType\":2},{\"AnalogueData\":{\"1\":14319,\"3\":2898,\"4\":23,\"5\":10965},\"FType\":6},{\"AnalogueData\":{\"11\":34,\"12\":3,\"13\":331,\"14\":11241,\"15\":3},\"FType\":7}]}]}"))); -- cgit v1.2.3 From 5b262c14aaf48919232abe9c41cb0d3288e56427 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Sep 2021 18:50:16 -0700 Subject: Decode telemetry messages --- .../protocol/NavtelecomProtocolDecoder.java | 217 ++++++++++++++++++--- .../protocol/NavtelecomProtocolDecoderTest.java | 6 + 2 files changed, 194 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 0e9685356..c469025c2 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -19,12 +19,22 @@ 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 { @@ -32,6 +42,67 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private static final Map 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; + + private 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; + } + private void sendResponse( Channel channel, SocketAddress remoteAddress, int receiver, int sender, ByteBuf content) { if (channel != null) { @@ -55,35 +126,123 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; - 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")) { - - String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); - getDeviceSession(channel, remoteAddress, sentence.substring(4)); - - ByteBuf payload = Unpooled.copiedBuffer("*FLEX")) { - - buf.skipBytes(6); - - ByteBuf payload = Unpooled.buffer(); - payload.writeCharSequence("*S")) { + + String sentence = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + getDeviceSession(channel, remoteAddress, sentence.substring(4)); + + ByteBuf payload = Unpooled.copiedBuffer("*FLEX")) { + + buf.skipBytes(6); + + ByteBuf payload = Unpooled.buffer(); + payload.writeCharSequence("* 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; + + } } diff --git a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java index be51cb852..fd22049fc 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class NavtelecomProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "404e5443010000000000000013004e452a3e533a383636373935303331343130363839")); + verifyNull(decoder, binary( + "404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000")); + + verifyPositions(decoder, binary( + "7e4104022106000517c4ae2f6180a9000e2fc4ae2f61471dff0171b35801d2050000a9870e412801d9d096466a37061000009474270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0308000000000000090cf70900000826fa000200b3ad2b00000826fa000200aad75200000826fa000200aa9cae2f6158020000000000000000000a14000000000000000000000000000000000000000026000000032106000b17dbae2f6180a9000e33daae2f61a11dff01edb15801d00500009c50e83f2f01ecd09646793706100000ab74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f61fd080000000000000000000a140100000000000000000000000000000000000000260000000421060054a0e7ae2f6180a9000e33e6ae2f61ba1dff01beb15801d305000038b977402201f0d09646163706100000b674270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0309000000000000080bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f6173040000000000000000000a14080000000000000000000000000000000000000026000000052106000517efae2f6180a9000f33efae2f61c21dff0166b15801df05000017f145404d00f5d09646693706100000bf74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090cf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f615b030000000000000000000a14020000000000000000000000000000000000000026000000a9")); + verifyNull(decoder, binary( "404e544301000000000000001300f7fc2a3e464c4558b00a0a45fffe00000000000000")); -- cgit v1.2.3 From 2204c9830058fe33a4bf426636468a9ec0749a83 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Sep 2021 12:27:53 -0700 Subject: Add custom frame decoder --- .../traccar/protocol/NavtelecomFrameDecoder.java | 75 ++++++++++++++++++++++ .../org/traccar/protocol/NavtelecomProtocol.java | 5 +- .../protocol/NavtelecomProtocolDecoder.java | 6 +- .../protocol/NavtelecomFrameDecoderTest.java | 44 +++++++++++++ 4 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java create mode 100644 src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java diff --git a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java new file mode 100644 index 000000000..0fb82528b --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java @@ -0,0 +1,75 @@ +/* + * 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 24bfbf895..29ce8c41e 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -15,20 +15,17 @@ */ 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 LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 65535, 12, 2, 2, 0, true)); + pipeline.addLast(new NavtelecomFrameDecoder()); 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 c469025c2..bdcc12c4c 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -95,7 +95,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { private BitSet bits; - private static int getItemLength(int id) { + 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)); @@ -103,6 +103,10 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { return length; } + public BitSet getBits() { + return bits; + } + private void sendResponse( Channel channel, SocketAddress remoteAddress, int receiver, int sender, ByteBuf content) { if (channel != null) { diff --git a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java new file mode 100644 index 000000000..07b19651b --- /dev/null +++ b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java @@ -0,0 +1,44 @@ +package org.traccar.protocol; + +import org.junit.Ignore; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class NavtelecomFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new NavtelecomFrameDecoder(); + + verifyFrame( + binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), + decoder.decode(null, null, binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"))); + + verifyFrame( + binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"), + decoder.decode(null, null, binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"))); + + } + + @Ignore + @Test + public void testDecodeFull() throws Exception { + + var decoder = new NavtelecomFrameDecoder(); + + verifyFrame( + binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), + decoder.decode(null, null, binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"))); + + verifyFrame( + binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"), + decoder.decode(null, null, binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"))); + + verifyFrame( + binary("7e4104022106000517c4ae2f6180a9000e2fc4ae2f61471dff0171b35801d2050000a9870e412801d9d096466a37061000009474270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0308000000000000090cf70900000826fa000200b3ad2b00000826fa000200aad75200000826fa000200aa9cae2f6158020000000000000000000a14000000000000000000000000000000000000000026000000032106000b17dbae2f6180a9000e33daae2f61a11dff01edb15801d00500009c50e83f2f01ecd09646793706100000ab74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f61fd080000000000000000000a140100000000000000000000000000000000000000260000000421060054a0e7ae2f6180a9000e33e6ae2f61ba1dff01beb15801d305000038b977402201f0d09646163706100000b674270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0309000000000000080bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f6173040000000000000000000a14080000000000000000000000000000000000000026000000052106000517efae2f6180a9000f33efae2f61c21dff0166b15801df05000017f145404d00f5d09646693706100000bf74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090cf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f615b030000000000000000000a14020000000000000000000000000000000000000026000000a9"), + decoder.decode(null, null, binary("7e4104022106000517c4ae2f6180a9000e2fc4ae2f61471dff0171b35801d2050000a9870e412801d9d096466a37061000009474270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0308000000000000090cf70900000826fa000200b3ad2b00000826fa000200aad75200000826fa000200aa9cae2f6158020000000000000000000a14000000000000000000000000000000000000000026000000032106000b17dbae2f6180a9000e33daae2f61a11dff01edb15801d00500009c50e83f2f01ecd09646793706100000ab74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f61fd080000000000000000000a140100000000000000000000000000000000000000260000000421060054a0e7ae2f6180a9000e33e6ae2f61ba1dff01beb15801d305000038b977402201f0d09646163706100000b674270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0309000000000000080bf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f6173040000000000000000000a14080000000000000000000000000000000000000026000000052106000517efae2f6180a9000f33efae2f61c21dff0166b15801df05000017f145404d00f5d09646693706100000bf74270080ff7f00000000ffff8000000000ffffffffffffffffffffffffffff7f00000000ffffff0408000000000000090cf70900000826fa000200af8bc70000256cfa000200ab3e7c0000256cfa000200aad7ae2f615b030000000000000000000a14020000000000000000000000000000000000000026000000a9"))); + + } + +} -- cgit v1.2.3 From 83cff6dd3876fa81d3f3257f1fb3f72cbdf38e70 Mon Sep 17 00:00:00 2001 From: soshial Date: Tue, 28 Sep 2021 11:51:38 +0200 Subject: shorten IF clause --- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 19d72d8a1..6331ff773 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -74,7 +74,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filterDuplicate(Position position, Position last) { - if (filterDuplicate && last != null && position.getFixTime().getTime() == last.getFixTime().getTime()) { + if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { for (String key : position.getAttributes().keySet()) { if (!last.getAttributes().containsKey(key)) { return false; -- cgit v1.2.3 From d7ed8ea799e9c0006e154f26969a6905b81eae0f Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 29 Sep 2021 16:08:01 -0300 Subject: fix bug in here geocoder formatted address fix bug in here geocoder formatted address --- src/main/java/org/traccar/geocoder/HereGeocoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/geocoder/HereGeocoder.java b/src/main/java/org/traccar/geocoder/HereGeocoder.java index aaf11d74d..40390e65b 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 (json.containsKey("Label")) { - address.setFormattedAddress(json.getString("Label")); + if (result.containsKey("Label")) { + address.setFormattedAddress(result.getString("Label")); } if (result.containsKey("HouseNumber")) { -- cgit v1.2.3 From c1b406b6fcc442f96f9698774f5544ec9a0588e9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Sep 2021 20:37:47 -0700 Subject: Decode ADC values --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 4d77d554e..05411addf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -333,6 +333,10 @@ 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; -- cgit v1.2.3 From c7a7f1e016f952cfaf9fe2e54d300a5259fa3676 Mon Sep 17 00:00:00 2001 From: soshial Date: Thu, 30 Sep 2021 16:43:58 +0400 Subject: Improve OpenCellId logging Add error message received from OpenCellId geolocation provider --- .../org/traccar/geolocation/OpenCellIdGeolocationProvider.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index cb3094e16..5e9779f2d 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -48,8 +48,14 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { callback.onSuccess( json.getJsonNumber("lat").doubleValue(), json.getJsonNumber("lon").doubleValue(), 0); + } else if (json.containsKey("error")) { + String errorMessage = json.getJsonString("error").getString(); + if (json.containsKey("code")) { + errorMessage += " Error code: " + json.getInt("code"); + } + callback.onFailure(new GeolocationException(errorMessage)); } else { - callback.onFailure(new GeolocationException("Coordinates are missing")); + callback.onFailure(new GeolocationException("Coordinates are missing.")); } } -- cgit v1.2.3 From a7431f4cccd273c6e56e5a099c71f2a4b5b76197 Mon Sep 17 00:00:00 2001 From: jcardus Date: Thu, 30 Sep 2021 19:20:41 -0300 Subject: Update MobilogixProtocolDecoder.java We are losing data from the events with two digits like T21 and T22 (ignition on and off). Also included the event code --- src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index 8677ba9ec..efefaf627 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -39,7 +39,7 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .text("[") .number("(dddd)-(dd)-(dd) ") // date (yyyymmdd) .number("(dd):(dd):(dd),") // time (hhmmss) - .number("Td,") // type + .number("Td+,") // type .number("d+,") // device type .expression("[^,]+,") // protocol version .expression("([^,]+),") // serial number @@ -80,6 +80,7 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); + position.set(Position.KEY_EVENT, type); position.setTime(parser.nextDateTime()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); -- cgit v1.2.3 From eafe26117e9cc52c58f4ce220f8ac0d5e1d9bf36 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 1 Oct 2021 20:22:21 -0700 Subject: Fix Bluetooth decoding --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 5 +++-- src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index bee21982e..0e829e7f7 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -461,9 +461,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_TYPE, type); - int mask = Integer.parseInt(values[index++], 16); + int mask; if (type.equals("BLE")) { mask = 0b1100000110110; + } else { + mask = Integer.parseInt(values[index++], 16); } if (BitUtil.check(mask, 1)) { @@ -518,7 +520,6 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setValid(true); int count = Integer.parseInt(values[index++]); - index += 1; for (int i = 1; i <= count; i++) { position.set("tag" + i + "Rssi", Integer.parseInt(values[index++])); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 7f0700728..a9720f437 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -83,7 +83,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = new SuntechProtocolDecoder(null); verifyPosition(decoder, buffer( - "BLE;0820012345;001FFF;82;1.0.0;20191203;17:00:51;+32.691615;-117.297160;2;2;-32;-100;33;AABBCCDDEEFF;12;18;52;1;-44;44;112233445566;32;69;101")); + "BLE;1140000053;114;1.0.1;20211001;17:27:09;+28.433465;-82.565891;1;-43;-46;-41;ACB89523EF68;247;0;0")); + + verifyPosition(decoder, buffer( + "BLE;0820012345;82;1.0.0;20191203;17:00:51;+32.691615;-117.297160;2;-32;-100;33;AABBCCDDEEFF;12;18;52;1;-44;44;112233445566;32;69;101")); verifyNull(decoder, buffer( "BSA;0820012345;001FFF;82;1.0.0;1;20191203;17:00:51;+32.691615;-117.297160;1;-55;68:11:6A:FD:1A:A7;6AA5;1DE8")); -- cgit v1.2.3 From 55803843eb2f9ea90b5fd712d2549305062d7a2c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Oct 2021 12:05:40 -0700 Subject: Disable session persistence --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index f9529d465..e1f8eb046 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,7 +12,7 @@ 8082 ./web - true + false false google -- cgit v1.2.3 From 7bd438a9d86b64bd1339c235c58105408e702de8 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 4 Oct 2021 14:52:23 +0200 Subject: reorganise IF clause (OpenCellId) --- .../geolocation/OpenCellIdGeolocationProvider.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 5e9779f2d..3b64a9a14 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -48,14 +48,16 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { callback.onSuccess( json.getJsonNumber("lat").doubleValue(), json.getJsonNumber("lon").doubleValue(), 0); - } else if (json.containsKey("error")) { - String errorMessage = json.getJsonString("error").getString(); - if (json.containsKey("code")) { - errorMessage += " Error code: " + json.getInt("code"); - } - callback.onFailure(new GeolocationException(errorMessage)); } else { - callback.onFailure(new GeolocationException("Coordinates are missing.")); + if (json.containsKey("error")) { + String errorMessage = json.getJsonString("error").getString(); + if (json.containsKey("code")) { + errorMessage += " (" + json.getInt("code") + ")"; + } + callback.onFailure(new GeolocationException(errorMessage)); + } else { + callback.onFailure(new GeolocationException("Coordinates are missing")); + } } } -- cgit v1.2.3 From 5118f5e281de16f5b17d147da462b6cfb16e4d4d Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 4 Oct 2021 18:58:02 +0200 Subject: fix Json decoding error (OpenCellId) --- .../java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 3b64a9a14..2535970d3 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -50,7 +50,7 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { json.getJsonNumber("lon").doubleValue(), 0); } else { if (json.containsKey("error")) { - String errorMessage = json.getJsonString("error").getString(); + String errorMessage = json.getString("error"); if (json.containsKey("code")) { errorMessage += " (" + json.getInt("code") + ")"; } -- cgit v1.2.3 From 6f90e144603ee8e15fa98d4053806dbf13c3ee10 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Oct 2021 23:19:29 -0700 Subject: Add test case --- src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index d0143ac97..9ac7dc050 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { var decoder = new DmtHttpProtocolDecoder(null); + verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("{\"date\":\"2021-10-04T18:14:55Z\",\"device\":{\"sn\":\"403809\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278483601922\",\"imei\":\"352656106127312\"},\"sqn\":40925,\"reason\":1,\"lat\":26.87366,\"lng\":-80.10618,\"posAcc\":47.7,\"posInfo\":{\"GDOP\":4.68,\"BSat\":2,\"GSat\":4,\"Src\":1},\"analogues\":[{\"id\":1,\"val\":4265},{\"id\":3,\"val\":3800},{\"id\":4,\"val\":16},{\"id\":5,\"val\":4255}],\"inputs\":1,\"outputs\":0,\"status\":137}"))); + verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{ \"date\": \"2021-04-20T11:10:03.702659861Z\", \"device\":{ \"sn\": \"0016C001F000ABEC\", \"prod\": 0.2, \"rev\": 0.3, \"fw\": \"1.1\", \"module\": \"LR 34.3.3\", \"iccid\": \"89610180000000000000\", \"imei\": \"354043000000000\" }, \"sqn\": 347263802, \"reason\":3, \"lat\": 1.1, \"lng\": 2.2, \"posAcc\": 30.1, \"posInfo\":{ \"HDOP\": 0.1, \"PDOP\": 0.2, \"GDOP\": 0.3, \"BSat\":1, \"GSat\":2, \"Src\":2 }, \"analogues\":[{ \"id\":1, \"val\": 300 },{ \"id\":2, \"val\": 500} ], \"inputs\": 5001, \"outputs\":0, \"status\": 17, \"counters\":[{ \"id\": 11, \"val\": 43 },{ \"id\": 23, \"val\": 8800} ], \"lora\":{ \"dev_id\": \"yabby-abec\", \"app_id\": \"digital-matter\", \"dev_addr\": \"260B567A\", \"gw\": [ { \"id\": \"dm-sentrius\", \"snr\": 10, \"rssi\": -36 } ] }}"))); -- cgit v1.2.3 From 90d5b6ff470aea80679b05ba690fe0630f111dc7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Oct 2021 22:39:13 -0700 Subject: Support TT18 4G format --- .../org/traccar/protocol/TzoneProtocolDecoder.java | 57 ++++++++++++++++------ .../traccar/protocol/TzoneProtocolDecoderTest.java | 3 ++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 4f6854098..4680e0a2f 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -21,6 +21,7 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; +import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -256,9 +257,28 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { int blockLength = buf.readUnsignedShort(); int blockEnd = buf.readerIndex() + blockLength; - if (blockLength > 0 && (hardware == 0x10A || hardware == 0x10B || hardware == 0x406)) { - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + 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); + + } } buf.readerIndex(blockEnd); @@ -272,21 +292,30 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("terminalInfo", buf.readUnsignedByte()); - 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); + 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); + } } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("gsmStatus", buf.readUnsignedByte()); 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 (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 { + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); + position.set("humidity", buf.readUnsignedShort()); + position.set("lightSensor", buf.readUnsignedByte()); + } } if (blockLength >= 15) { diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index 0aeea0f1a..fba8f7db4 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { var decoder = new TzoneProtocolDecoder(null); + verifyAttributes(decoder, binary( + "545a004d24240407010d0000018032100000031515090c052c2100000022030a033400201347000056860a03340020134700002feb0a03340020134700007d96000baa10211f01810127022d000001ebe00d0a")); + verifyAttributes(decoder, binary( "545A004B2424041302000000086706003324776413030C0A1A2900180513030C0A1A25080F7E1028CAC830000A000F0000000005000AA53201633D05046000010009AA201737019408973B0032B0260D0A")); -- cgit v1.2.3 From 1f37392e344faae3eb717ffe39f4c182b752ad2d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 7 Oct 2021 09:21:33 -0700 Subject: Better events API errors --- src/main/java/org/traccar/api/resource/EventResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index e0ccf7020..f0a71d30d 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -7,7 +7,9 @@ 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; @@ -25,6 +27,9 @@ 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()); -- cgit v1.2.3 From 5121d5bc446f8e6a2350c50038a9baa5deb09d4c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 7 Oct 2021 09:22:19 -0700 Subject: Add missing license notice --- src/main/java/org/traccar/api/resource/EventResource.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index f0a71d30d..34e4a94ce 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -1,3 +1,18 @@ +/* + * 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; -- cgit v1.2.3 From 6802e2657378e8e3eec7de742d5690f3978cfa2d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 7 Oct 2021 09:26:51 -0700 Subject: Handle missing coordinates --- .../org/traccar/protocol/DmtHttpProtocolDecoder.java | 16 +++++++++++----- .../org/traccar/protocol/DmtHttpProtocolDecoderTest.java | 3 +++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index ebf9a006c..cffc1f3eb 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -159,11 +159,17 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - position.setTime(new Date(OffsetDateTime.parse(root.getString("date")).toInstant().toEpochMilli())); - position.setLatitude(root.getJsonNumber("lat").doubleValue()); - position.setLongitude(root.getJsonNumber("lng").doubleValue()); - position.setAccuracy(root.getJsonNumber("posAcc").doubleValue()); + 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")); diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index 9ac7dc050..bed56ba30 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { var decoder = new DmtHttpProtocolDecoder(null); + verifyAttributes(decoder, request(HttpMethod.POST, "/", + buffer("{\"date\":\"2021-10-04T18:15:47Z\",\"device\":{\"sn\":\"403809\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278483601922\",\"imei\":\"352656106127312\"},\"sqn\":40927,\"reason\":11,\"analogues\":[{\"id\":1,\"val\":4265},{\"id\":3,\"val\":3800},{\"id\":4,\"val\":12},{\"id\":5,\"val\":4251}],\"inputs\":1,\"outputs\":0,\"status\":137}"))); + verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"date\":\"2021-10-04T18:14:55Z\",\"device\":{\"sn\":\"403809\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278483601922\",\"imei\":\"352656106127312\"},\"sqn\":40925,\"reason\":1,\"lat\":26.87366,\"lng\":-80.10618,\"posAcc\":47.7,\"posInfo\":{\"GDOP\":4.68,\"BSat\":2,\"GSat\":4,\"Src\":1},\"analogues\":[{\"id\":1,\"val\":4265},{\"id\":3,\"val\":3800},{\"id\":4,\"val\":16},{\"id\":5,\"val\":4255}],\"inputs\":1,\"outputs\":0,\"status\":137}"))); -- cgit v1.2.3 From 2bae9c0587249e5281ea090ec8f3a3f22ed7ed0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Oct 2021 22:52:05 -0700 Subject: Add modular response --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index b313802b3..47c422907 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1143,7 +1143,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); - return decodeExtendedModular(buf, deviceSession); + return decodeExtendedModular(channel, buf, deviceSession); } else { @@ -1154,7 +1154,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeExtendedModular(ByteBuf buf, DeviceSession deviceSession) { + private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -1255,6 +1255,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } + sendResponse(channel, true, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); + return position; } -- cgit v1.2.3 From 28ed925ab358c0db24f779c0574c4dba3c63d326 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Oct 2021 22:54:02 -0700 Subject: Revert "Add modular response" This reverts commit 2bae9c0587249e5281ea090ec8f3a3f22ed7ed0e. --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 47c422907..b313802b3 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1143,7 +1143,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); - return decodeExtendedModular(channel, buf, deviceSession); + return decodeExtendedModular(buf, deviceSession); } else { @@ -1154,7 +1154,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,8 +1255,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - sendResponse(channel, true, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - return position; } -- cgit v1.2.3 From 53ee85d47e851615e271c7ac80675877365509a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Oct 2021 22:54:35 -0700 Subject: Revert "Fix response" This reverts commit daa63a3aa7ae0c7092e24d0a536e78bdd785ae35. --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index b313802b3..0c8ecd4a9 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1141,7 +1141,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); + sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); return decodeExtendedModular(buf, deviceSession); -- cgit v1.2.3 From cdb2d2aa151f900bf16af22538b6049daf7e494c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Oct 2021 22:55:29 -0700 Subject: Refactor response --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0c8ecd4a9..a9da34e6e 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1141,9 +1141,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); - - return decodeExtendedModular(buf, deviceSession); + return decodeExtendedModular(channel, buf, deviceSession); } else { @@ -1154,7 +1152,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeExtendedModular(ByteBuf buf, DeviceSession deviceSession) { + private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -1255,6 +1253,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } + sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); + return position; } -- cgit v1.2.3 From 91e6409a0c012106cec454e5953fab2e4b558972 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Oct 2021 16:10:53 -0700 Subject: Handle no location --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 4 ++++ src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index a9da34e6e..4c71d3724 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1253,6 +1253,10 @@ 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/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index fd1eb3040..3caba32e6 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "797900377000000001020035000103002c0004616219d00043000b013601048153931500001a0001000808652820400643521000000101004e46760d0a")); + verifyNull(decoder, binary( "7878171915061810051a01f90101700d08c8f50c0000065494ae0d0a")); -- cgit v1.2.3 From 1ed18df76447d01ace02ec29856d4bd9c7720e83 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Oct 2021 16:24:37 -0700 Subject: Fix decoding --- .../java/org/traccar/protocol/TzoneProtocolDecoder.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 4680e0a2f..b8477dcb6 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -288,7 +288,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { blockLength = buf.readUnsignedShort(); blockEnd = buf.readerIndex() + blockLength; - if (blockLength >= 13) { + if (hardware == 0x407 || blockLength >= 13) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("terminalInfo", buf.readUnsignedByte()); @@ -312,9 +312,16 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); } else { - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); - position.set("humidity", buf.readUnsignedShort()); - position.set("lightSensor", buf.readUnsignedByte()); + int temperature = buf.readUnsignedShort(); + if (!BitUtil.check(temperature, 15)) { + double value = BitUtil.to(temperature, 14) * 0.01; + 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)); + } + position.set("lightSensor", buf.readUnsignedByte() == 0); } } -- cgit v1.2.3 From f9823f2763689ee94645385dcd5e3427ec7255b0 Mon Sep 17 00:00:00 2001 From: jcardus Date: Tue, 12 Oct 2021 00:48:48 +0100 Subject: added a position with a T21 event in the test case --- src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index dc60edb15..aff4e42a6 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "[2020-12-01 12:01:09,T3,1,V1.1.1,201951132031,3B,12.99,022,-23.563410,-46.588055,0,0")); + verifyPosition(decoder, text( + "[2021-09-30 20:06:35,T21,1,V1.3.5,201950130047,37,14.97,092,-23.494715,-46.851341,0,240,4.08,0,19516,4431,0.78,724,10,09111,00771,31,4680")); + } } -- cgit v1.2.3 From f643887684f3dff65a954fba1ada36e8b81db9d3 Mon Sep 17 00:00:00 2001 From: jcardus Date: Tue, 12 Oct 2021 01:31:56 +0100 Subject: use key instead of event --- src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index efefaf627..ac75841a4 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -80,13 +80,13 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - position.set(Position.KEY_EVENT, type); position.setTime(parser.nextDateTime()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + position.set(Position.KEY_TYPE, type); position.setDeviceId(deviceSession.getDeviceId()); int status = parser.nextHexInt(); -- cgit v1.2.3 From 6d737a665b905b8e4394d63962386ce51ef96509 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Oct 2021 20:11:55 -0700 Subject: Minor cleanup --- src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index ac75841a4..00e297faa 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -86,9 +86,10 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } - position.set(Position.KEY_TYPE, type); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); + int status = parser.nextHexInt(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); position.set(Position.KEY_MOTION, BitUtil.check(status, 3)); -- cgit v1.2.3 From aeb560b9eb988960e2964c4e329899723dd70891 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Oct 2021 21:15:58 -0700 Subject: Support Hoopo platform API --- setup/default.xml | 1 + .../java/org/traccar/protocol/HoopoProtocol.java | 39 +++++++++++ .../org/traccar/protocol/HoopoProtocolDecoder.java | 80 ++++++++++++++++++++++ .../traccar/protocol/HoopoProtocolDecoderTest.java | 19 +++++ 4 files changed, 139 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/HoopoProtocol.java create mode 100644 src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index e1f8eb046..05f6625d3 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -296,5 +296,6 @@ 5228 5229 5230 + 5231 diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java new file mode 100644 index 000000000..d47327ad8 --- /dev/null +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -0,0 +1,39 @@ +/* + * 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.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class HoopoProtocol extends BaseProtocol { + + public HoopoProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(65535)); + 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 new file mode 100644 index 000000000..4f6b3d546 --- /dev/null +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -0,0 +1,80 @@ +/* + * 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 io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import org.traccar.BaseHttpProtocolDecoder; +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.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.util.Date; + +public class HoopoProtocolDecoder extends BaseHttpProtocolDecoder { + + public HoopoProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + String content = request.content().toString(StandardCharsets.UTF_8); + JsonObject json = Json.createReader(new StringReader(content)).readObject(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("deviceId")); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + 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(eventData.getString("receiveTime")).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; + + } + + sendResponse(channel, HttpResponseStatus.OK); + + return null; + } + +} diff --git a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java new file mode 100644 index 000000000..37f838dd4 --- /dev/null +++ b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpMethod; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class HoopoProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new HoopoProtocolDecoder(null); + + verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }"))); + + } + +} -- cgit v1.2.3 From d6d8a33bd28a5e9c2e712f0a2f7041cb681a28d7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Oct 2021 22:54:11 -0700 Subject: Support JT701 devices --- src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java | 6 +++--- src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java | 4 ++++ src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index d745153a4..37c1674d4 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -87,7 +87,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } static boolean isLongFormat(ByteBuf buf, int flagIndex) { - return buf.getUnsignedByte(flagIndex) >> 4 == 0x7; + return buf.getUnsignedByte(flagIndex) >> 4 >= 7; } static void decodeBinaryLocation(ByteBuf buf, Position position) { @@ -176,7 +176,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { cellTower.setSignalStrength((int) buf.readUnsignedByte()); position.setNetwork(new Network(cellTower)); - if (protocolVersion == 0x17) { + if (protocolVersion == 0x17 || protocolVersion == 0x19) { buf.readUnsignedByte(); // geofence id buf.skipBytes(3); // reserved buf.skipBytes(buf.readableBytes() - 1); diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java index cd2d5b102..eda97ba2d 100644 --- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java @@ -10,6 +10,10 @@ public class Jt600FrameDecoderTest extends ProtocolTest { var decoder = new Jt600FrameDecoder(); + verifyFrame( + binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"), + decoder.decode(null, null, binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"))); + verifyFrame( binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274"), decoder.decode(null, null, binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274"))); diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index be384c0f1..3c681ec58 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { var decoder = new Jt600ProtocolDecoder(null); + verifyPositions(decoder, binary( + "2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e")); + verifyPositions(decoder, binary( "2478807035371711003419081920061851380856003256223b000000000000070000000020c0ff965d54de1800000f0f0f0f0f0f0f0f0f0f02d600ea0a21")); -- cgit v1.2.3 From 0061b510de1ea71ad5d827f8b7cddfd1cc8dd759 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Oct 2021 23:13:02 -0700 Subject: Support TLW2-12BL format --- .../org/traccar/protocol/T800xProtocolDecoder.java | 21 +++++++++++++++------ .../traccar/protocol/T800xProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 72b277c8c..7c7fa3320 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -58,6 +58,8 @@ 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) { @@ -134,11 +136,11 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_GPS && type != MSG_ALARM) { + if (type != MSG_GPS && type != MSG_GPS_2 && type != MSG_ALARM) { sendResponse(channel, header, type, index, imei, 0); } - if (type == MSG_GPS || type == MSG_ALARM) { + if (type == MSG_GPS || type == MSG_GPS_2 ||type == MSG_ALARM || type == MSG_ALARM_2) { return decodePosition(channel, deviceSession, buf, type, index, imei); @@ -343,12 +345,19 @@ 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)); - 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 (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)); + } if (header != 0x2626) { - for (int i = 1; i <= 2; i++) { + int adcCount = type == MSG_GPS_2 || type == MSG_ALARM_2 ? 5 : 2; + for (int i = 1; i <= adcCount; i++) { String value = ByteBufUtil.hexDump(buf.readSlice(2)); if (!value.equals("ffff")) { position.set(Position.PREFIX_ADC + i, Integer.parseInt(value) * 0.01); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index 61fb658a6..1dd4e8619 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class T800xProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, binary( "27271000277bb30860112047066487210407022840000004e6215130c50fff620a0c1518000156")); + verifyPosition(decoder, binary( + "252514005901c00867730050941347001e46501e03e80064f2c0001401000041000000000000000000ffffffff160000034ec40021100719073800000000c2fb90c21291fd400000000003961237ffff0000002effffffffff")); + verifyPosition(decoder, binary( "27270200497d880860112047066487470021040702270500006442d4e2e342f671b441000000008000008080881dff3900000384700640003c0000001e1e00641e30d2800000000000")); -- cgit v1.2.3 From 1696a32c40dc4c54b8e895ad91af0bed5340b16a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Oct 2021 23:17:50 -0700 Subject: Fix code style issue --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 7c7fa3320..0f54cbd87 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -140,7 +140,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, header, type, index, imei, 0); } - if (type == MSG_GPS || type == MSG_GPS_2 ||type == MSG_ALARM || type == MSG_ALARM_2) { + if (type == MSG_GPS || type == MSG_GPS_2 || type == MSG_ALARM || type == MSG_ALARM_2) { return decodePosition(channel, deviceSession, buf, type, index, imei); -- cgit v1.2.3 From 1bf9940a5f6abed56afa4e90ed20d1dfdff17cc2 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 12 Oct 2021 19:07:54 +0200 Subject: fix: Totem - Per documentation the response DataType should always be AA. Partially reverts commit ebd0688, fixes #4755 --- src/main/java/org/traccar/protocol/TotemProtocolDecoder.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index b5398116d..90a3db4c0 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -461,10 +461,8 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - String type = null; if (pattern == PATTERN4) { - type = parser.next(); - position.set(Position.KEY_ALARM, decodeAlarm4(Integer.parseInt(type, 16))); + position.set(Position.KEY_ALARM, decodeAlarm4(parser.nextHexInt())); } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); @@ -485,8 +483,8 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - if (type != null) { - String response = "$$0014" + type + sentence.substring(sentence.length() - 6, sentence.length() - 2); + if (pattern == PATTERN4) { + String response = "$$0014AA" + sentence.substring(sentence.length() - 6, sentence.length() - 2); response += String.format("%02X", Checksum.xor(response)).toUpperCase(); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { -- cgit v1.2.3 From 68c28833f6298e2f3d7dd53197fe16880cbb99be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Oct 2021 23:14:46 -0700 Subject: Fix decoding --- src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index b8477dcb6..249915b39 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -305,7 +305,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("gsmStatus", buf.readUnsignedByte()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); if (hardware != 0x407) { position.set(Position.KEY_POWER, buf.readUnsignedShort()); @@ -314,12 +314,12 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } else { int temperature = buf.readUnsignedShort(); if (!BitUtil.check(temperature, 15)) { - double value = BitUtil.to(temperature, 14) * 0.01; + 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)); + position.set("humidity", BitUtil.to(humidity, 15) * 0.1); } position.set("lightSensor", buf.readUnsignedByte() == 0); } -- cgit v1.2.3 From 55183c8ff9774573e7a43175eb3f75fb558ce768 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Oct 2021 23:25:42 -0700 Subject: Fix responses --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 0f54cbd87..93acdbf2b 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -136,11 +136,12 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_GPS && type != MSG_GPS_2 && type != MSG_ALARM) { + boolean positionType = type == MSG_GPS || type == MSG_GPS_2 || type == MSG_ALARM || type == MSG_ALARM_2; + if (!positionType) { sendResponse(channel, header, type, index, imei, 0); } - if (type == MSG_GPS || type == MSG_GPS_2 || type == MSG_ALARM || type == MSG_ALARM_2) { + if (positionType) { return decodePosition(channel, deviceSession, buf, type, index, imei); -- cgit v1.2.3 From 49424c999ec8eba6b8c3f2003ddae35137abbc38 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Oct 2021 20:49:17 -0700 Subject: No response for normal positions --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 93acdbf2b..7f7873e50 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -483,7 +483,9 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - sendResponse(channel, header, type, index, imei, alarm); + if (type == MSG_ALARM || type == MSG_ALARM_2) { + sendResponse(channel, header, type, index, imei, alarm); + } return position; } -- cgit v1.2.3 From 9552097653a88ed26b89356b7cce3eabe1833aeb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Oct 2021 23:54:46 -0700 Subject: Remove conflicting attribute --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 0cc2319a4..2eb0c351a 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -235,9 +235,6 @@ 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: -- cgit v1.2.3 From 3c218ef8d2ff1474446e637e8abd9c97c4a47df1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 15 Oct 2021 12:25:45 -0700 Subject: Decode additional Square3X data --- src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java | 7 +++++++ .../java/org/traccar/protocol/HuaShengProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 2e1ddf5f2..891046213 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -262,6 +262,13 @@ 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/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index 51a5d18ae..74671b845 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { var decoder = new HuaShengProtocolDecoder(null); + verifyNull(decoder, binary( + "c00000007eaa000000000000cb8000000032313130313030393238323800e9abafffd615d2000000000008000000010015ffffff0000000000000004e7ffffffffff0005000a10080001d5ab000900154b4e4142323531324d4b54353638363630000f00133335343434343131353130333138380014000b00000000000000c0")); + verifyNull(decoder, binary( "c0010c003c0002000000000044020010a0014f42445f3347315f56322e320013a0043335353835353035313032303536360006a08700000006a0a105c9c0")); -- cgit v1.2.3 From b5acde4beda190efd63c1acfab7c38f6590f7bf1 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Fri, 15 Oct 2021 23:28:07 +0200 Subject: fix: Totem - additional Alarm and Vehicle Status decoding --- .../java/org/traccar/protocol/TotemProtocolDecoder.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 90a3db4c0..f7d0ffde7 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -227,8 +227,22 @@ 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_SHOCK; + case 0x41: + return Position.ALARM_IDLE; case 0x42: return Position.ALARM_ACCELERATION; case 0x43: @@ -357,6 +371,7 @@ 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)); @@ -365,6 +380,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { 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 - 17) ? Position.ALARM_IDLE : 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); -- cgit v1.2.3 From a31c75e93ea9ff6b42f54a1869ab87a88222e28a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Oct 2021 09:37:34 -0700 Subject: Remove io389 mapping (fix #4760) --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2eb0c351a..89ae48b3a 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -299,11 +299,6 @@ 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; -- cgit v1.2.3 From 7c04066ff6444790acd8b28d1abffd46bd8243da Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Oct 2021 12:04:18 -0700 Subject: Decode counter values --- .../org/traccar/protocol/DmtHttpProtocolDecoder.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index cffc1f3eb..8283ab643 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -184,6 +184,25 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_OUTPUT, root.getInt("outputs")); 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; } -- cgit v1.2.3 From 78a6d42d3ddc1755d3754c148996f7804d076ccf Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 20 Oct 2021 20:13:52 +0200 Subject: fix: Totem - More accurate/generic Vehicle Status decoding so it does not show wrong values for AT07 --- .../org/traccar/protocol/TotemProtocolDecoder.java | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index f7d0ffde7..758f7f9ba 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -372,17 +372,31 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { 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_IO + 8, BitUtil.check(status, 32 - 8)); // GPS Module Error 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.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 - 17) ? Position.ALARM_IDLE : 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); + + /** + * Different Devices have different meaning for bits 12-22 + * But unfortunately we cannot reliably detect this, so we use generic IO notation + * + * | AT05 | AT07 | AT09 + * 12 | Reserved | IN2 | OUT4 + * 13 | IN2 | IN4 | IN2 + * 14 | IN3 | Shock | IN3 + * 15 | IN4 | Idle | IN4 + * 16 | Shock | Low Batt. | Shock + * 17 | Idle | Drv. Auth. | Idle + * 18 | Low Batt. | GPS Status | Low Batt. + * 19 | Drv. Auth. | Batt. chrg.| Drv. Auth. + * 20 | GPS Status | GSM Jamming| GPS Status + * 21 | Batt. chrg.| Reserved | Batt. chrg. + * 22 | Reserved | Reserved | GSM Jamming + */ + for (int i = 12; i < 23; i++) { + position.set(Position.PREFIX_IO + i, BitUtil.check(status, 32 - i)); + } position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From 3c52988d6549dfd271693096bbf86ed17e532737 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 20 Oct 2021 20:26:13 +0200 Subject: fix: Build/style warning --- src/main/java/org/traccar/protocol/TotemProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 758f7f9ba..1d4100932 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -395,7 +395,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { * 22 | Reserved | Reserved | GSM Jamming */ for (int i = 12; i < 23; i++) { - position.set(Position.PREFIX_IO + i, BitUtil.check(status, 32 - i)); + position.set(Position.PREFIX_IO + i, BitUtil.check(status, 32 - i)); } position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From b4de72d4a0bf73998224d08a3bd2ba8310d83f8d Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 20 Oct 2021 20:39:16 +0200 Subject: fix: Totem - remove individual bit decoding and store the whole status in KEY_STATUS --- .../org/traccar/protocol/TotemProtocolDecoder.java | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 1d4100932..81948f16d 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -372,31 +372,16 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { 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_IO + 8, BitUtil.check(status, 32 - 8)); // GPS Module Error 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)); /** * Different Devices have different meaning for bits 12-22 - * But unfortunately we cannot reliably detect this, so we use generic IO notation - * - * | AT05 | AT07 | AT09 - * 12 | Reserved | IN2 | OUT4 - * 13 | IN2 | IN4 | IN2 - * 14 | IN3 | Shock | IN3 - * 15 | IN4 | Idle | IN4 - * 16 | Shock | Low Batt. | Shock - * 17 | Idle | Drv. Auth. | Idle - * 18 | Low Batt. | GPS Status | Low Batt. - * 19 | Drv. Auth. | Batt. chrg.| Drv. Auth. - * 20 | GPS Status | GSM Jamming| GPS Status - * 21 | Batt. chrg.| Reserved | Batt. chrg. - * 22 | Reserved | Reserved | GSM Jamming + * But unfortunately we cannot reliably detect this, so we store the whole status in KEY_STATUS + * See: https://github.com/traccar/traccar/pull/4762 */ - for (int i = 12; i < 23; i++) { - position.set(Position.PREFIX_IO + i, BitUtil.check(status, 32 - i)); - } + position.set(Position.KEY_STATUS, status); position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From 72ada0ce78ee824b2d54cc4d37311ddd7cd216ee Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Wed, 20 Oct 2021 20:42:20 +0200 Subject: Update src/main/java/org/traccar/protocol/TotemProtocolDecoder.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/TotemProtocolDecoder.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 81948f16d..dc4347f00 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -375,13 +375,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { 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)); - - /** - * Different Devices have different meaning for bits 12-22 - * But unfortunately we cannot reliably detect this, so we store the whole status in KEY_STATUS - * See: https://github.com/traccar/traccar/pull/4762 - */ - position.set(Position.KEY_STATUS, status); + position.set(Position.KEY_STATUS, status); // see https://github.com/traccar/traccar/pull/4762 position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From b3b7d02c36dc42670294062e7c66e70d4b9c4f2e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Oct 2021 16:11:15 -0700 Subject: Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d58c51b9..633140be1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Overview -Traccar is an open source GPS tracking system. This repository contains Java-based back-end service. It supports more than 170 GPS protocols and more than 1500 models of GPS tracking devices. Traccar can be used with any major SQL database system. It also provides easy to use [REST API](https://www.traccar.org/traccar-api/). +Traccar is an open source GPS tracking system. This repository contains Java-based back-end service. It supports more than 200 GPS protocols and more than 2000 models of GPS tracking devices. Traccar can be used with any major SQL database system. It also provides easy to use [REST API](https://www.traccar.org/traccar-api/). Other parts of Traccar solution include: -- cgit v1.2.3 From 7f1cb863872c01aaf7defa8164940b729eb86b77 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Oct 2021 21:09:20 -0700 Subject: Remove duplicated character --- src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index 9562a75e2..1b3f6fcbb 100644 --- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { var decoder = new Xt2400ProtocolDecoder(null); - decoder.setConfig("\n::wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n"); + decoder.setConfig("\n:wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n"); verifyPosition(decoder, binary( "010ae85be10801a05d52d590030b12d1f9330be9290a0000ff10008b00000000000000000000000000000000000000000000000000000000000000000000000000003839333032363930323031303036363039373733000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000")); -- cgit v1.2.3 From 36bcdfc80dc19bc932f03bc8a0da056f46023304 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Oct 2021 20:26:45 -0700 Subject: Expect TCP JSON data --- .../java/org/traccar/protocol/HoopoProtocol.java | 11 ++--- .../org/traccar/protocol/HoopoProtocolDecoder.java | 14 ++---- .../org/traccar/protocol/JsonFrameDecoder.java | 55 ++++++++++++++++++++++ .../java/org/traccar/protocol/StbFrameDecoder.java | 55 ---------------------- .../java/org/traccar/protocol/StbProtocol.java | 2 +- .../traccar/protocol/HoopoProtocolDecoderTest.java | 5 +- .../org/traccar/protocol/JsonFrameDecoderTest.java | 19 ++++++++ .../org/traccar/protocol/StbFrameDecoderTest.java | 19 -------- 8 files changed, 85 insertions(+), 95 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/JsonFrameDecoder.java delete mode 100644 src/main/java/org/traccar/protocol/StbFrameDecoder.java create mode 100644 src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java delete mode 100644 src/test/java/org/traccar/protocol/StbFrameDecoderTest.java diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index d47327ad8..387b967d3 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; +import 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; @@ -28,9 +27,9 @@ public class HoopoProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); + 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 index 4f6b3d546..5db7f0bc0 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -16,9 +16,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; @@ -27,11 +25,10 @@ import javax.json.Json; import javax.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; import java.time.OffsetDateTime; import java.util.Date; -public class HoopoProtocolDecoder extends BaseHttpProtocolDecoder { +public class HoopoProtocolDecoder extends BaseProtocolDecoder { public HoopoProtocolDecoder(Protocol protocol) { super(protocol); @@ -41,13 +38,10 @@ public class HoopoProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - FullHttpRequest request = (FullHttpRequest) msg; - String content = request.content().toString(StandardCharsets.UTF_8); - JsonObject json = Json.createReader(new StringReader(content)).readObject(); + JsonObject json = Json.createReader(new StringReader((String) msg)).readObject(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("deviceId")); if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); return null; } @@ -72,8 +66,6 @@ public class HoopoProtocolDecoder extends BaseHttpProtocolDecoder { } - sendResponse(channel, HttpResponseStatus.OK); - return null; } diff --git a/src/main/java/org/traccar/protocol/JsonFrameDecoder.java b/src/main/java/org/traccar/protocol/JsonFrameDecoder.java new file mode 100644 index 000000000..b2d7fbd53 --- /dev/null +++ b/src/main/java/org/traccar/protocol/JsonFrameDecoder.java @@ -0,0 +1,55 @@ +/* + * 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 JsonFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int startIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '{'); + if (startIndex >= 0) { + + buf.readerIndex(startIndex); + + int currentIndex = startIndex + 1; + int nesting = 1; + while (currentIndex < buf.writerIndex() && nesting > 0) { + byte currentByte = buf.getByte(currentIndex); + if (currentByte == '{') { + nesting += 1; + } else if (currentByte == '}') { + nesting -= 1; + } + currentIndex += 1; + } + + if (nesting == 0) { + return buf.readRetainedSlice(currentIndex - startIndex); + } + + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/StbFrameDecoder.java b/src/main/java/org/traccar/protocol/StbFrameDecoder.java deleted file mode 100644 index 6a4157f17..000000000 --- a/src/main/java/org/traccar/protocol/StbFrameDecoder.java +++ /dev/null @@ -1,55 +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 StbFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - int startIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '{'); - if (startIndex >= 0) { - - buf.readerIndex(startIndex); - - int currentIndex = startIndex + 1; - int nesting = 1; - while (currentIndex < buf.writerIndex() && nesting > 0) { - byte currentByte = buf.getByte(currentIndex); - if (currentByte == '{') { - nesting += 1; - } else if (currentByte == '}') { - nesting -= 1; - } - currentIndex += 1; - } - - if (nesting == 0) { - return buf.readRetainedSlice(currentIndex - startIndex); - } - - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index ca95787d0..002ed86c7 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 StbFrameDecoder()); + pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StbProtocolDecoder(StbProtocol.this)); diff --git a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java index 37f838dd4..35d0f1423 100644 --- a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java @@ -1,6 +1,5 @@ package org.traccar.protocol; -import io.netty.handler.codec.http.HttpMethod; import org.junit.Test; import org.traccar.ProtocolTest; @@ -11,8 +10,8 @@ public class HoopoProtocolDecoderTest extends ProtocolTest { var decoder = new HoopoProtocolDecoder(null); - verifyPosition(decoder, request(HttpMethod.POST, "/", - buffer("{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }"))); + verifyPosition(decoder, text( + "{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }")); } diff --git a/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java new file mode 100644 index 000000000..42777e419 --- /dev/null +++ b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class JsonFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new JsonFrameDecoder(); + + verifyFrame( + binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"), + decoder.decode(null, null, binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/StbFrameDecoderTest.java b/src/test/java/org/traccar/protocol/StbFrameDecoderTest.java deleted file mode 100644 index 45d998fb1..000000000 --- a/src/test/java/org/traccar/protocol/StbFrameDecoderTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - -public class StbFrameDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - var decoder = new StbFrameDecoder(); - - verifyFrame( - binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"), - decoder.decode(null, null, binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"))); - - } - -} -- cgit v1.2.3 From f686847115097cf388a775fad6f13b8bf6893193 Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Fri, 22 Oct 2021 11:45:35 +0200 Subject: title-added --- src/main/java/org/traccar/config/Keys.java | 7 +++++++ .../traccar/notificators/NotificatorFirebase.java | 21 ++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1411e8a13..f037c632f 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -744,6 +744,13 @@ public final class Keys { "notificator.firebase.key", Collections.singletonList(KeyType.GLOBAL)); + /** + * Firebase push notifications title. + */ + public static final ConfigKey NOTIFICATOR_FIREBASE_TITLE = new ConfigKey<>( + "notificator.firebase.title", + Collections.singletonList(KeyType.GLOBAL)); + /** * Pushover notification user name. */ diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 78d5da1e2..cd084080e 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -37,6 +37,8 @@ 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") @@ -67,6 +69,7 @@ public class NotificatorFirebase extends Notificator { if (user.getAttributes().containsKey("notificationTokens")) { Notification notification = new Notification(); + notification.title=Context.getConfig().getString(Keys.NOTIFICATOR_FIREBASE_TITLE); notification.body = NotificationFormatter.formatShortMessage(userId, event, position).trim(); notification.sound = "default"; @@ -77,15 +80,15 @@ public class NotificatorFirebase extends Notificator { Context.getClient().target(url).request() .header("Authorization", "key=" + key) .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Firebase notification error", throwable); - } - }); + @Override + public void completed(Object o) { + } + + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Firebase notification error", throwable); + } + }); } } -- cgit v1.2.3 From 0dab261a9ec77811c073b328018675d5f9d71fe6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 25 Oct 2021 18:52:12 -0700 Subject: Handle no cell info --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index a6b89dde4..4990cfd65 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 = Integer.parseInt(values[index++]); - int mnc = Integer.parseInt(values[index++]); + int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; for (int i = 0; i < cellCount; i++) { network.addCellTower(CellTower.from(mcc, mnc, diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 4544b5827..98e83f491 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -19,6 +19,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { "[3G*2104326058*000E*btemp2,1,35.29]"), Position.PREFIX_TEMP + 1, 35.29); + verifyPosition(decoder, buffer( + "[SG*9059056143*0053*UD,251021,223408,A,41.46500,N,081.53128,W,0.926,000,0,00,70,70,0,50,00000000,0,1,,,,00]")); + verifyPosition(decoder, buffer( "[3G*2104326058*00E9*UD_LTE,300621,135101,A,32.162652,N,34.888748,E,30.84,265.158,65.621,18,100,83,0,0,00000000,1,1,425,01,10223,8012811,100,3,ES4104,22:74:1d:39:64:ff,-46,metropoline-wifi,a8:3f:a1:e0:66:ba,-89,Egged.co.il,00:0c:42:51:cf:cd,-81,1.7055488]")); -- cgit v1.2.3 From 3593d6075cbc40460e91cfccb4f2fb7c9913e315 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Oct 2021 22:58:23 -0700 Subject: Fix responses --- .../traccar/protocol/MobilogixProtocolDecoder.java | 6 ++-- .../protocol/MobilogixProtocolDecoderTest.java | 38 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index 00e297faa..ba70a8884 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -60,7 +60,7 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - String type = sentence.substring(21, 21 + 2); + String type = sentence.substring(21, sentence.indexOf(',', 21)); if (channel != null) { String time = sentence.substring(1, 20); @@ -68,12 +68,12 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { if (type.equals("T1")) { response = String.format("[%s,S1,1]", time); } else { - response = String.format("[%s,S%c]", time, type.charAt(1)); + response = String.format("[%s,S%s]", time, type.substring(1)); } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - Parser parser = new Parser(PATTERN, (String) msg); + Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index aff4e42a6..efa46b9f6 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class MobilogixProtocolDecoderTest extends ProtocolTest { @@ -13,6 +14,43 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "[2020-12-01 14:00:22,T1,1,V1.1.1,201951132031,,,12345678,724108005415815,359366080211420")); + verifyNull(decoder, text( + "[2020-10-25 20:44:08,T8,1,V1.2.3,201951132044,3596")); + + verifyPosition(decoder, text( + "[2020-10-25 20:45:09,T9,1,V1.2.3,201951132044,59,10.50,701,-25.236860,-45.708530,0,314")); + + verifyPosition(decoder, text( + "[2021-10-25 20:46:10,T10,1,V1.2.3,201951132044,59,0.50,082,-25.909590,-47.045387,0,145")); + + verifyPosition(decoder, text( + "[2021-10-25 20:47:11,T11,1,V1.2.3,201951132044,3F,9.23,991,-25.909262,-47.045387,1,341")); + + verifyPosition(decoder, text( + "[2021-10-25 20:54:11,T12,1,V1.2.3,201951132044,3F,9.23,991,-25.909262,-47.045387,1,341")); + + verifyNull(decoder, text( + "[2021-10-25 20:48:14,T14,1,V1.2.3,201951132044,51,0.50")); + + verifyPosition(decoder, text( + "[2021-10-25 20:49:15,T15,1,V1.2.3,201951132044,59,0.50,591,-25.908621,-47.045971,2,127")); + + verifyNull(decoder, text( + "[2021-10-25 20:50:16,T16,1,V1.2.3,201951132044,1")); + + verifyPosition(decoder, text( + "[2021-10-25 20:51:21,T21,1,V1.2.3,201951132044,37,12.18,961,-25.932310,-47.022415,0,82")); + + verifyPosition(decoder, text( + "[2021-10-25 20:52:22,T22,1,V1.2.3,201951132044,1B,12.05,082,-25.909590,-47.045387,0,145")); + + verifyPosition(decoder, text( + "[2021-10-25 20:53:31,T31,1,V1.2.3,201951132044,D3,26.17,961,-23.458092,-46.392132,0,8")); + + verifyAttribute(decoder, text( + "[2021-10-25 20:55:11,T13,1,V1.2.3,201951132044,3F,9.23,991,-25.909262,-47.045387,1,341"), + Position.KEY_TYPE, "T13"); + verifyPosition(decoder, text( "[2020-12-01 12:01:09,T3,1,V1.1.1,201951132031,3B,12.99,022,-23.563410,-46.588055,0,0")); -- cgit v1.2.3 From b90829bf06ff2f150a9818224a10b825906cd686 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 27 Oct 2021 23:25:29 -0700 Subject: Decode magnetic card --- src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java | 7 ++++++- .../java/org/traccar/protocol/FifotrackProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 70972f847..4a23d57d0 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -206,7 +206,12 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt())); + 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); + } } if (parser.hasNext()) { diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index fdac158dd..218cafbeb 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { var decoder = new FifotrackProtocolDecoder(null); + verifyPosition(decoder, buffer( + "$$274,863003046499158,18D0,A01,,211026081639,A,13.934116,100.000463,0,263,16,366959,345180,80000040,02,0,520|0|FA8|1A9B5B9,9DE|141|2D,% ^YENSABAICHAI$SONGKRAN$MR.^^?;6007643190300472637=150519870412=?+ 14 1 0000155 00103 ?,*69")); + verifyAttribute(decoder, buffer( "$$25,863003046473534,1,B03,OK*4D"), Position.KEY_RESULT, "OK"); -- cgit v1.2.3 From de44291fc5f23703176d8c6b872420319357fd84 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Oct 2021 22:05:14 -0700 Subject: Support Fifotrack A03 format --- .../traccar/protocol/FifotrackProtocolDecoder.java | 91 ++++++++++++++++++++++ .../protocol/FifotrackProtocolDecoderTest.java | 6 ++ 2 files changed, 97 insertions(+) diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 4a23d57d0..5f9326a61 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -31,6 +31,7 @@ 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; @@ -74,6 +75,37 @@ 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 @@ -160,6 +192,61 @@ 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) { @@ -301,6 +388,10 @@ 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/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index 218cafbeb..6480d1dc4 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { var decoder = new FifotrackProtocolDecoder(null); + verifyPosition(decoder, buffer( + "$$95,866104023192332,1,A03,,210414055249,460|0|25FC|104C,4.18,100,000F,0,A,2,9,22.643175,114.018150*75")); + + verifyAttributes(decoder, buffer( + "$$136,866104023192332,1,A03,,210414055249,460|0|25FC|104C,4.18,100,000F,1,94D9B377EB53:-60|EC6C9FA4CAD8:-55|CA50E9206252:-61|54E061260A89:-51*3E")); + verifyPosition(decoder, buffer( "$$274,863003046499158,18D0,A01,,211026081639,A,13.934116,100.000463,0,263,16,366959,345180,80000040,02,0,520|0|FA8|1A9B5B9,9DE|141|2D,% ^YENSABAICHAI$SONGKRAN$MR.^^?;6007643190300472637=150519870412=?+ 14 1 0000155 00103 ?,*69")); -- cgit v1.2.3 From fb60f434eccef5e4d0f9e3e9eca75ca73d01d2bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Oct 2021 15:44:55 -0700 Subject: Support Teltonika Dualcam protocol --- setup/default.xml | 1 + .../org/traccar/protocol/DualcamFrameDecoder.java | 49 ++++++++ .../java/org/traccar/protocol/DualcamProtocol.java | 34 ++++++ .../traccar/protocol/DualcamProtocolDecoder.java | 124 +++++++++++++++++++++ .../traccar/protocol/DualcamFrameDecoderTest.java | 23 ++++ .../protocol/DualcamProtocolDecoderTest.java | 27 +++++ 6 files changed, 258 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/DualcamFrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/DualcamProtocol.java create mode 100644 src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java create mode 100644 src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 05f6625d3..4d4de39b0 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -297,5 +297,6 @@ 5229 5230 5231 + 5232 diff --git a/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java b/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java new file mode 100644 index 000000000..312d43f19 --- /dev/null +++ b/src/main/java/org/traccar/protocol/DualcamFrameDecoder.java @@ -0,0 +1,49 @@ +/* + * 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 new file mode 100644 index 000000000..9f8d6778e --- /dev/null +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -0,0 +1,34 @@ +/* + * 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 DualcamProtocolDecoder(DualcamProtocol.this)); + pipeline.addLast(new DishaProtocolDecoder(DualcamProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java new file mode 100644 index 000000000..4647e287c --- /dev/null +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -0,0 +1,124 @@ +/* + * 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) { + if (BitUtil.check(settings, 26)) { + ByteBuf response = Unpooled.buffer(); + response.writeShort(MSG_FILE_REQUEST); + String file = "%photof"; + response.writeShort(file.length()); + response.writeCharSequence(file, StandardCharsets.US_ASCII); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } else { + ByteBuf response = Unpooled.buffer(); + 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()); + 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)); + } + } else { + currentPacket += 1; + } + break; + default: + break; + } + + return null; + } + +} diff --git a/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java new file mode 100644 index 000000000..46f32a8ae --- /dev/null +++ b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class DualcamFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new DualcamFrameDecoder(); + + verifyFrame( + binary("000000050001403a4abaa31444000400"), + decoder.decode(null, null, binary("000000050001403a4abaa31444000400"))); + + verifyFrame( + binary("00010006000000110000"), + decoder.decode(null, null, binary("00010006000000110000"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java new file mode 100644 index 000000000..3dd11bdf7 --- /dev/null +++ b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java @@ -0,0 +1,27 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class DualcamProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new DualcamProtocolDecoder(null); + + verifyNull(decoder, binary( + "000000050001403a4abaa31444000400")); + + verifyNull(decoder, binary( + "00010006000000110000")); + + verifyNull(decoder, binary( + "0003000400000001")); + + verifyNull(decoder, binary( + "00040402ffd8ffe000104a46494600010100000100010000ffdb00c500100b0c0e0c0a100e0d0e1211101318281a181616183123251d283a333d3c3933383740485c4e404457453738506d51575f626768673e4d71797064785c656763011112121815182f1a1a2f634238426363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363021112121815182f1a1a2f634238426363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363ffc000110801e0028003012200021101031102ffc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f00cb97c350585ac0fabea5f61966dd88bc8326307d54fa107f1a65f787c5be9b1ea36575f6cb46cee93cbf2f6fcc14704e4e4e7f2aaba0e873eb574638cec893fd64b8076641c71919c918ad3d635881edd74bd246cd3d3a9c93e66486fe219186cf7e6818cd3742f3f4e7bfbbb8fb2db0c6d7d9bf77241e01c8c1c7e74dd63479b49b908e77c4ff00eae4e06ec019e32718cd751e24b1fed1bfd36d7ccf2f7f9bf36338c007a7e155107fc5bf00ff009fded2199ede1f8ad2085f52befb24b2eefddf9464c60faa9fa7e751ea1a2f91a7a5f5acff0069b639dcfb366de401c1393cff002a6e8fa44ba8cc510ec8d7efc9c1dbc1c719e7a558d6b5588c034ed386cb25ea793bf90ddc6460e68028e91a44dab5c948cec893fd6498076e41c71919ce2a7bbb0fecebb7b5f33ccd98f9b18ce403d3f1ab3e16d4af3fb46dac3ceff46f9fe4da3d09eb8cf5a975e1ff0013ab8ff80ffe82293d83a99c48740004040217d696b47fb0f51ff9f7ff00c7d7fc6a2b8d2af6da169a6876c6bd4ef53df1d8d2025b4d2fcdb37bbb89bc880636b6dddbb9c74073d69ba8e9d269f30563b91bee3f4ddd33c678eb5b7addafdb2f2c6df7ecdfe67cd8ce3001fe9500ff009147fcff00cf4a2c229c9a4c56f146d7d75f6777ce13cb2fd3dc1fa54777a6795669756f379f01cee6dbb71ce3a139eb51e9da7c9a84c554ed45fbefd76f5c719e7a558d47508cc42cac46db55fa9dfd0f7191839a0665370b4a9c0abeda26a27a5bff00e3ebfe351cda5dedb42d2cf0ed45ea7729f6ec695809ad74cf3acdaeae25f22118dadb77679c74073d6a9eb3a749a6cbcfcc8df75fa6ec633c67deba2d72dbed977636dbf6799e67cd8ce3001fe9550f3e0bff003ff3d29b42b941b468eda085b51bbfb34926711888be307d54fd3f3a6dde8c8b62b750ca2e2dce72c536639c0e09cf5aaf611dbb97fb45dfd9f18dbfbb2fbbf2e95b9767cbf0e2a5bfefe039dd37ddc7cffdd3cf5e285619")); + + } + +} -- cgit v1.2.3 From e046f7dd34a000f8c56671a0f344e9c56fcaf899 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Oct 2021 16:23:20 -0700 Subject: Merge shock and vibration alarms --- src/main/java/org/traccar/model/Position.java | 1 - src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/EsealProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 4 ++-- src/main/java/org/traccar/protocol/TotemProtocolDecoder.java | 2 +- 10 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 6f70c8e21..09d25e832 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -136,7 +136,6 @@ 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/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 6a31cb2f4..83e62ff86 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_SHOCK; + return Position.ALARM_VIBRATION; case 0x3: return Position.ALARM_POWER_CUT; case 0x4: diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index cc7f6e935..0a12f781d 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_SHOCK; + return Position.ALARM_VIBRATION; case "Event-Drop": return Position.ALARM_FALL_DOWN; case "Event-Lock": diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 0a0d04db0..83ca74ce5 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_SHOCK); + position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); } return true; case "overspeeding.event.trigger": diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index 0284ff6c7..d74f19179 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -157,7 +157,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { case "accident alarm": return Position.ALARM_ACCIDENT; case "sensor alarm": - return Position.ALARM_SHOCK; + return Position.ALARM_VIBRATION; case "bonnet alarm": return Position.ALARM_BONNET; case "footbrake alarm": diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4c71d3724..45218aba2 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -319,7 +319,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { switch (BitUtil.between(status, 3, 6)) { case 1: - position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); + position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); break; case 2: position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 4abb75025..45890e9a2 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_SHOCK; + return Position.ALARM_VIBRATION; 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 e63dd3b32..7233280c2 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_SHOCK; + return Position.ALARM_VIBRATION; case "belt on": case "belton": return Position.ALARM_LOCK; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 0e829e7f7..2d00ea81e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -161,7 +161,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case 7: return Position.ALARM_MOVEMENT; case 8: - return Position.ALARM_SHOCK; + return Position.ALARM_VIBRATION; default: return null; } @@ -178,7 +178,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case 14: return Position.ALARM_LOW_BATTERY; case 15: - return Position.ALARM_SHOCK; + return Position.ALARM_VIBRATION; case 16: return Position.ALARM_ACCIDENT; case 40: diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index dc4347f00..58c66031e 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -240,7 +240,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { case 0x13: return Position.ALARM_LOW_BATTERY; case 0x40: - return Position.ALARM_SHOCK; + return Position.ALARM_VIBRATION; case 0x41: return Position.ALARM_IDLE; case 0x42: -- cgit v1.2.3 From dd7d1c19d3f8e50f79a057af0e2aee70165ac82f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Oct 2021 17:06:40 -0700 Subject: Handle SP4600 command responses --- src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java | 9 +++++++-- .../java/org/traccar/protocol/GoSafeProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index 76278070e..a86249224 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -187,7 +187,12 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { int index = 0; String[] fragments = sentence.split(","); - position.setTime(new SimpleDateFormat("HHmmssddMMyy").parse(fragments[index++])); + 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++]); + } for (; index < fragments.length; index += 1) { if (!fragments[index].isEmpty()) { diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java index 3ede9017f..bb79f4f25 100644 --- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest { var decoder = new GoSafeProtocolDecoder(null); + verifyPositions(decoder, false, text( + "*GS06,357330050846344,RST#")); + verifyAttribute(decoder, text( "*GS06,356449068350122,013519070819,,SYS:G6S;V3.37;V1.1.8,GPS:A;12;N23.169866;E113.450728;0;255;54;0.79,COT:18779;,ADC:12.66;0.58,DTT:4084;E1;0;0;0;1,IWD:0;1;ad031652643fff28;23.2;1;1;86031652504fff28;24.3;2;1;e603165252a5ff28;24.2;3;1;bb0416557da6ff28;24.0#"), Position.PREFIX_TEMP + 3, 24.0); -- cgit v1.2.3 From 4a00ea7be7c0a7102d5a19c8fcc2cdcec58319af Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Oct 2021 21:45:54 -0700 Subject: Decode Edge ignition value --- .../java/org/traccar/protocol/DmtHttpProtocolDecoder.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 8283ab643..15cf84a5f 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -180,9 +180,15 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.PREFIX_ADC + adc.getInt("id"), adc.getInt("val")); } - position.set(Position.KEY_INPUT, root.getInt("inputs")); - position.set(Position.KEY_OUTPUT, root.getInt("outputs")); - position.set(Position.KEY_STATUS, root.getInt("status")); + int input = root.getInt("inputs"); + int output = root.getInt("outputs"); + int status = root.getInt("status"); + + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, output); + position.set(Position.KEY_STATUS, status); if (root.containsKey("counters")) { JsonArray counters = root.getJsonArray("counters"); -- cgit v1.2.3 From 12b26830b3eae6fac9e87c462fc09cfe6c962964 Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Tue, 2 Nov 2021 16:22:03 +0100 Subject: short-message-title-from-templates --- src/main/java/org/traccar/config/Keys.java | 7 ----- .../notification/NotificationFormatter.java | 2 +- .../org/traccar/notification/ShortMessage.java | 36 ++++++++++++++++++++++ .../notification/TextTemplateFormatter.java | 5 +-- .../traccar/notificators/NotificatorFirebase.java | 8 +++-- .../traccar/notificators/NotificatorPushover.java | 8 ++++- .../org/traccar/notificators/NotificatorSms.java | 7 +++-- .../traccar/notificators/NotificatorTelegram.java | 5 ++- templates/short/alarm.vm | 1 + templates/short/commandResult.vm | 1 + templates/short/deviceFuelDrop.vm | 1 + templates/short/deviceInactive.vm | 1 + templates/short/deviceMoving.vm | 1 + templates/short/deviceOffline.vm | 1 + templates/short/deviceOnline.vm | 1 + templates/short/deviceOverspeed.vm | 1 + templates/short/deviceStopped.vm | 1 + templates/short/deviceUnknown.vm | 1 + templates/short/driverChanged.vm | 1 + templates/short/geofenceEnter.vm | 1 + templates/short/geofenceExit.vm | 1 + templates/short/ignitionOff.vm | 1 + templates/short/ignitionOn.vm | 1 + templates/short/maintenance.vm | 1 + templates/short/test.vm | 1 + templates/short/textMessage.vm | 1 + templates/short/unknown.vm | 1 + 27 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/traccar/notification/ShortMessage.java diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f037c632f..1411e8a13 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -744,13 +744,6 @@ public final class Keys { "notificator.firebase.key", Collections.singletonList(KeyType.GLOBAL)); - /** - * Firebase push notifications title. - */ - public static final ConfigKey NOTIFICATOR_FIREBASE_TITLE = new ConfigKey<>( - "notificator.firebase.title", - Collections.singletonList(KeyType.GLOBAL)); - /** * Pushover notification user name. */ diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index dabc75b8b..f33961c8b 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -63,7 +63,7 @@ public final class NotificationFormatter { return TextTemplateFormatter.formatFullMessage(velocityContext, event.getType()); } - public static String formatShortMessage(long userId, Event event, Position position) { + public static ShortMessage 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/ShortMessage.java b/src/main/java/org/traccar/notification/ShortMessage.java new file mode 100644 index 000000000..a0ee61def --- /dev/null +++ b/src/main/java/org/traccar/notification/ShortMessage.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.notification; + +public class ShortMessage { + + private String title; + private String body; + + public ShortMessage(String subject, String body) { + this.title = subject; + this.body = body; + } + + public String getTitle() { + return title; + } + + public String getBody() { + return body; + } +} diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index c7cac2d4d..8a4d35677 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -76,8 +76,9 @@ public final class TextTemplateFormatter { return new FullMessage((String) velocityContext.get("subject"), formattedMessage); } - public static String formatShortMessage(VelocityContext velocityContext, String name) { - return formatMessage(velocityContext, name, "short"); + public static ShortMessage formatShortMessage(VelocityContext velocityContext, String name) { + String formattedMessage = formatMessage(velocityContext, name, "short"); + return new ShortMessage((String) velocityContext.get("title"), formattedMessage); } private static String formatMessage( diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index cd084080e..9d1982f9c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -24,7 +24,9 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.FullMessage; import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -68,9 +70,11 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { + ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Notification notification = new Notification(); - notification.title=Context.getConfig().getString(Keys.NOTIFICATOR_FIREBASE_TITLE); - notification.body = NotificationFormatter.formatShortMessage(userId, event, position).trim(); + notification.title= shortMessage.getTitle(); + notification.body = shortMessage.getBody(); notification.sound = "default"; Message message = new Message(); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 189af7834..e541ea525 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,6 +24,7 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -43,6 +44,8 @@ public class NotificatorPushover extends Notificator { private String user; @JsonProperty("device") private String device; + @JsonProperty("title") + private String title; @JsonProperty("message") private String message; } @@ -74,11 +77,14 @@ public class NotificatorPushover extends Notificator { return; } + ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message message = new Message(); message.token = token; message.user = this.user; message.device = device; - message.message = NotificationFormatter.formatShortMessage(userId, event, position); + message.title= shortMessage.getTitle(); + message.message = shortMessage.getBody(); Context.getClient().target(url).request() .async().post(Entity.json(message), new InvocationCallback() { diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 8124e40b1..360eb44ff 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -24,6 +24,7 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.ShortMessage; public final class NotificatorSms extends Notificator { @@ -31,9 +32,10 @@ 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) { + ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), - NotificationFormatter.formatShortMessage(userId, event, position), false); + shortMessage.getBody(), false); } } @@ -41,9 +43,10 @@ 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) { + ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), - NotificationFormatter.formatShortMessage(userId, event, position), false); + shortMessage.getBody(), false); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index dbba0d31d..a8cdacfbf 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,6 +25,7 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -98,12 +99,14 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); + ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); if (message.chatId == null) { message.chatId = chatId; } - message.text = NotificationFormatter.formatShortMessage(userId, event, position); + message.text = shortMessage.getBody(); executeRequest(urlSendText, message); if (sendLocation && position != null) { executeRequest(urlSendLocation, createLocationMessage(message.chatId, position)); diff --git a/templates/short/alarm.vm b/templates/short/alarm.vm index ce641781b..faab92291 100644 --- a/templates/short/alarm.vm +++ b/templates/short/alarm.vm @@ -1 +1,2 @@ +#set($title = "Alarm") $device.name alarm: $position.getString("alarm") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/commandResult.vm b/templates/short/commandResult.vm index 27fd668be..7b3986573 100644 --- a/templates/short/commandResult.vm +++ b/templates/short/commandResult.vm @@ -1 +1,2 @@ +#set($title = "Command Result") $device.name command result received: $position.getString("result") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceFuelDrop.vm b/templates/short/deviceFuelDrop.vm index 5eabe9cc0..2a4d2c608 100644 --- a/templates/short/deviceFuelDrop.vm +++ b/templates/short/deviceFuelDrop.vm @@ -1 +1,2 @@ +#set($title = "Fuel Drop") $device.name fuel drop at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceInactive.vm b/templates/short/deviceInactive.vm index d7431124c..f701ba408 100644 --- a/templates/short/deviceInactive.vm +++ b/templates/short/deviceInactive.vm @@ -1,3 +1,4 @@ +#set($title = "Inactive") #set($lastUpdate = $dateTool.getDate()) #set($ignore = $lastUpdate.setTime($event.getLong("lastUpdate"))) $device.name inactive from $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone) diff --git a/templates/short/deviceMoving.vm b/templates/short/deviceMoving.vm index a08becd2b..3307326d6 100644 --- a/templates/short/deviceMoving.vm +++ b/templates/short/deviceMoving.vm @@ -1 +1,2 @@ +#set($title = "Moving") $device.name moving at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOffline.vm b/templates/short/deviceOffline.vm index 1dac43ac6..1967970b3 100644 --- a/templates/short/deviceOffline.vm +++ b/templates/short/deviceOffline.vm @@ -1 +1,2 @@ +#set($title = "Offline") $device.name offline at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOnline.vm b/templates/short/deviceOnline.vm index 3c18097c1..65a59a8b3 100644 --- a/templates/short/deviceOnline.vm +++ b/templates/short/deviceOnline.vm @@ -1 +1,2 @@ +#set($title = "Online") $device.name online at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOverspeed.vm b/templates/short/deviceOverspeed.vm index fe318fe08..fa4d7b189 100644 --- a/templates/short/deviceOverspeed.vm +++ b/templates/short/deviceOverspeed.vm @@ -7,4 +7,5 @@ #else #set($speedString = $numberTool.format("0.0 kn", $position.speed)) #end +#set($title = "Overspeed") $device.name exceeds the speed $speedString#{if}($geofence) in $geofence.name#{else}#{end} at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceStopped.vm b/templates/short/deviceStopped.vm index 1a63630ba..42147782b 100644 --- a/templates/short/deviceStopped.vm +++ b/templates/short/deviceStopped.vm @@ -1 +1,2 @@ +#set($title = "Stopped") $device.name stopped at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceUnknown.vm b/templates/short/deviceUnknown.vm index 37baa30a7..b0fd2c42d 100644 --- a/templates/short/deviceUnknown.vm +++ b/templates/short/deviceUnknown.vm @@ -1 +1,2 @@ +#set($title = "Status unknown") $device.name status is unknown at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/driverChanged.vm b/templates/short/driverChanged.vm index 36ed8955e..fc9a6689e 100644 --- a/templates/short/driverChanged.vm +++ b/templates/short/driverChanged.vm @@ -3,4 +3,5 @@ #else #set($driverName = $event.getString("driverUniqueId")) #end +#set($title = "Driver changed") Driver $driverName has changed in $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceEnter.vm b/templates/short/geofenceEnter.vm index 962eecc53..79736b096 100644 --- a/templates/short/geofenceEnter.vm +++ b/templates/short/geofenceEnter.vm @@ -1 +1,2 @@ +#set($title = "Geofence entered") $device.name has entered geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceExit.vm b/templates/short/geofenceExit.vm index 47999fa94..db5243600 100644 --- a/templates/short/geofenceExit.vm +++ b/templates/short/geofenceExit.vm @@ -1 +1,2 @@ +#set($title = "Geofence exited") $device.name has exited geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOff.vm b/templates/short/ignitionOff.vm index 4d4b45ccc..953e8d0a5 100644 --- a/templates/short/ignitionOff.vm +++ b/templates/short/ignitionOff.vm @@ -1 +1,2 @@ +#set($title = "Ignition OFF") $device.name ignition OFF at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOn.vm b/templates/short/ignitionOn.vm index d8dd07966..610b8e272 100644 --- a/templates/short/ignitionOn.vm +++ b/templates/short/ignitionOn.vm @@ -1 +1,2 @@ +#set($title = "Ignition ON") $device.name ignition ON at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/maintenance.vm b/templates/short/maintenance.vm index a931e5c20..917345599 100644 --- a/templates/short/maintenance.vm +++ b/templates/short/maintenance.vm @@ -1 +1,2 @@ +#set($title = "Maintenance") $device.name maintenance $maintenance.name is required at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/test.vm b/templates/short/test.vm index d25f218ce..bd317d97b 100644 --- a/templates/short/test.vm +++ b/templates/short/test.vm @@ -1 +1,2 @@ +#set($title = "Test") Test message diff --git a/templates/short/textMessage.vm b/templates/short/textMessage.vm index 59fa7cbc6..456dcacd3 100644 --- a/templates/short/textMessage.vm +++ b/templates/short/textMessage.vm @@ -1 +1,2 @@ +#set($title = "Text message") Text message received from $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/unknown.vm b/templates/short/unknown.vm index fd20b50cc..a7259f6e9 100644 --- a/templates/short/unknown.vm +++ b/templates/short/unknown.vm @@ -1 +1,2 @@ +#set($title = "Unknown") Unknown type -- cgit v1.2.3 From 64d38de4a3c8063ca8aabdc5583843e6db3c9446 Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Tue, 2 Nov 2021 16:46:57 +0100 Subject: argument-subject-changed-to-title --- src/main/java/org/traccar/notification/ShortMessage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/notification/ShortMessage.java b/src/main/java/org/traccar/notification/ShortMessage.java index a0ee61def..28812a1f1 100644 --- a/src/main/java/org/traccar/notification/ShortMessage.java +++ b/src/main/java/org/traccar/notification/ShortMessage.java @@ -21,8 +21,8 @@ public class ShortMessage { private String title; private String body; - public ShortMessage(String subject, String body) { - this.title = subject; + public ShortMessage(String title, String body) { + this.title = title; this.body = body; } -- cgit v1.2.3 From 9fd24af30db35411de8d30b96be665f00d75c0ad Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Wed, 3 Nov 2021 09:42:35 +0100 Subject: redundant-code-removed --- .../org/traccar/api/resource/PasswordResource.java | 4 +-- .../java/org/traccar/notification/FullMessage.java | 36 -------------------- .../java/org/traccar/notification/Message.java | 36 ++++++++++++++++++++ .../notification/NotificationFormatter.java | 10 ++---- .../org/traccar/notification/ShortMessage.java | 36 -------------------- .../notification/TextTemplateFormatter.java | 13 +++----- .../traccar/notificators/NotificatorFirebase.java | 17 +++++----- .../org/traccar/notificators/NotificatorMail.java | 4 +-- .../traccar/notificators/NotificatorPushover.java | 38 +++++++++++----------- .../org/traccar/notificators/NotificatorSms.java | 6 ++-- .../traccar/notificators/NotificatorTelegram.java | 20 ++++++------ templates/short/alarm.vm | 2 +- templates/short/commandResult.vm | 2 +- templates/short/deviceFuelDrop.vm | 2 +- templates/short/deviceInactive.vm | 2 +- templates/short/deviceMoving.vm | 2 +- templates/short/deviceOffline.vm | 2 +- templates/short/deviceOnline.vm | 2 +- templates/short/deviceOverspeed.vm | 2 +- templates/short/deviceStopped.vm | 2 +- templates/short/deviceUnknown.vm | 2 +- templates/short/driverChanged.vm | 2 +- templates/short/geofenceEnter.vm | 2 +- templates/short/geofenceExit.vm | 2 +- templates/short/ignitionOff.vm | 2 +- templates/short/ignitionOn.vm | 2 +- templates/short/maintenance.vm | 2 +- templates/short/test.vm | 2 +- templates/short/textMessage.vm | 2 +- templates/short/unknown.vm | 2 +- 30 files changed, 105 insertions(+), 153 deletions(-) delete mode 100644 src/main/java/org/traccar/notification/FullMessage.java create mode 100644 src/main/java/org/traccar/notification/Message.java delete mode 100644 src/main/java/org/traccar/notification/ShortMessage.java diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 20e8d768d..16b0afc12 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.FullMessage; +import org.traccar.notification.Message; import org.traccar.notification.TextTemplateFormatter; import javax.annotation.security.PermitAll; @@ -53,7 +53,7 @@ public class PasswordResource extends BaseResource { Context.getUsersManager().updateItem(user); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); velocityContext.put("token", token); - FullMessage message = TextTemplateFormatter.formatFullMessage(velocityContext, "passwordReset"); + Message message = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); Context.getMailManager().sendMessage(userId, message.getSubject(), message.getBody()); break; } diff --git a/src/main/java/org/traccar/notification/FullMessage.java b/src/main/java/org/traccar/notification/FullMessage.java deleted file mode 100644 index f66537c6e..000000000 --- a/src/main/java/org/traccar/notification/FullMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.notification; - -public class FullMessage { - - private String subject; - private String body; - - public FullMessage(String subject, String body) { - this.subject = subject; - this.body = body; - } - - public String getSubject() { - return subject; - } - - public String getBody() { - return body; - } -} diff --git a/src/main/java/org/traccar/notification/Message.java b/src/main/java/org/traccar/notification/Message.java new file mode 100644 index 000000000..33f38007c --- /dev/null +++ b/src/main/java/org/traccar/notification/Message.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.notification; + +public class Message { + + private String subject; + private String body; + + public Message(String subject, String body) { + this.subject = subject; + this.body = body; + } + + public String getSubject() { + return subject; + } + + public String getBody() { + return body; + } +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index f33961c8b..3170d1204 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -58,14 +58,8 @@ public final class NotificationFormatter { return velocityContext; } - public static FullMessage formatFullMessage(long userId, Event event, Position position) { + public static Message formatMessage(long userId, Event event, Position position, String templatePath) { VelocityContext velocityContext = prepareContext(userId, event, position); - return TextTemplateFormatter.formatFullMessage(velocityContext, event.getType()); + return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } - - public static ShortMessage 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/ShortMessage.java b/src/main/java/org/traccar/notification/ShortMessage.java deleted file mode 100644 index 28812a1f1..000000000 --- a/src/main/java/org/traccar/notification/ShortMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.notification; - -public class ShortMessage { - - private String title; - private String body; - - public ShortMessage(String title, String body) { - this.title = title; - this.body = body; - } - - public String getTitle() { - return title; - } - - public String getBody() { - return body; - } -} diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 8a4d35677..77a2fea05 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -71,17 +71,12 @@ public final class TextTemplateFormatter { return template; } - public static FullMessage formatFullMessage(VelocityContext velocityContext, String name) { - String formattedMessage = formatMessage(velocityContext, name, "full"); - return new FullMessage((String) velocityContext.get("subject"), formattedMessage); + public static Message formatMessage(VelocityContext velocityContext, String name, String templatePath) { + String formattedMessage = format(velocityContext, name, templatePath); + return new Message((String) velocityContext.get("subject"), formattedMessage); } - public static ShortMessage formatShortMessage(VelocityContext velocityContext, String name) { - String formattedMessage = formatMessage(velocityContext, name, "short"); - return new ShortMessage((String) velocityContext.get("title"), formattedMessage); - } - - private static String formatMessage( + private static String format( VelocityContext velocityContext, String name, String templatePath) { StringWriter writer = new StringWriter(); diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 9d1982f9c..0f189a330 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -24,9 +24,8 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.FullMessage; +import org.traccar.notification.Message; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -47,7 +46,7 @@ public class NotificatorFirebase extends Notificator { private String sound; } - public static class Message { + public static class Payload { @JsonProperty("registration_ids") private String[] tokens; @JsonProperty("notification") @@ -70,20 +69,20 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Notification notification = new Notification(); - notification.title= shortMessage.getTitle(); + notification.title = shortMessage.getSubject(); notification.body = shortMessage.getBody(); notification.sound = "default"; - Message message = new Message(); - message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + Payload payload = new Payload(); + payload.tokens = user.getString("notificationTokens").split("[, ]"); + payload.notification = notification; Context.getClient().target(url).request() .header("Authorization", "key=" + key) - .async().post(Entity.json(message), new InvocationCallback() { + .async().post(Entity.json(payload), new InvocationCallback() { @Override public void completed(Object o) { } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 6b9774c58..339445622 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.FullMessage; +import org.traccar.notification.Message; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; @@ -30,7 +30,7 @@ public final class NotificatorMail extends Notificator { @Override public void sendSync(long userId, Event event, Position position) throws MessageException { try { - FullMessage message = NotificationFormatter.formatFullMessage(userId, event, position); + Message message = NotificationFormatter.formatMessage(userId, event, position, "full"); 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 e541ea525..4a3099d7c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -23,8 +23,8 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.Message; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -37,7 +37,7 @@ public class NotificatorPushover extends Notificator { private final String token; private final String user; - public static class Message { + public static class Payload { @JsonProperty("token") private String token; @JsonProperty("user") @@ -77,26 +77,26 @@ public class NotificatorPushover extends Notificator { return; } - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); - Message message = new Message(); - message.token = token; - message.user = this.user; - message.device = device; - message.title= shortMessage.getTitle(); - message.message = shortMessage.getBody(); + Payload payload = new Payload(); + payload.token = token; + payload.user = this.user; + payload.device = device; + payload.title = shortMessage.getSubject(); + payload.message = shortMessage.getBody(); Context.getClient().target(url).request() - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Pushover API error", throwable); - } - }); + .async().post(Entity.json(payload), new InvocationCallback() { + @Override + public void completed(Object o) { + } + + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Pushover API error", throwable); + } + }); } @Override diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 360eb44ff..1a4739c1a 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -22,9 +22,9 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.Message; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; public final class NotificatorSms extends Notificator { @@ -32,7 +32,7 @@ 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) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -43,7 +43,7 @@ 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) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a8cdacfbf..c85e2be3d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -24,8 +24,8 @@ import org.traccar.model.User; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.notification.Message; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -75,15 +75,15 @@ public class NotificatorTelegram extends Notificator { private void executeRequest(String url, Object message) { Context.getClient().target(url).request() .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } + @Override + public void completed(Object o) { + } - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Telegram API error", throwable); - } - }); + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Telegram API error", throwable); + } + }); } private LocationMessage createLocationMessage(String messageChatId, Position position) { @@ -99,7 +99,7 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + Message shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/templates/short/alarm.vm b/templates/short/alarm.vm index faab92291..15970dab8 100644 --- a/templates/short/alarm.vm +++ b/templates/short/alarm.vm @@ -1,2 +1,2 @@ -#set($title = "Alarm") +#set($subject = "$device.name: alarm!") $device.name alarm: $position.getString("alarm") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/commandResult.vm b/templates/short/commandResult.vm index 7b3986573..6dc7a5dec 100644 --- a/templates/short/commandResult.vm +++ b/templates/short/commandResult.vm @@ -1,2 +1,2 @@ -#set($title = "Command Result") +#set($subject = "$device.name: command result received") $device.name command result received: $position.getString("result") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceFuelDrop.vm b/templates/short/deviceFuelDrop.vm index 2a4d2c608..babe14351 100644 --- a/templates/short/deviceFuelDrop.vm +++ b/templates/short/deviceFuelDrop.vm @@ -1,2 +1,2 @@ -#set($title = "Fuel Drop") +#set($subject = "$device.name: fuel drop") $device.name fuel drop at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceInactive.vm b/templates/short/deviceInactive.vm index f701ba408..c293bf1b2 100644 --- a/templates/short/deviceInactive.vm +++ b/templates/short/deviceInactive.vm @@ -1,4 +1,4 @@ -#set($title = "Inactive") +#set($subject = "$device.name: inactive") #set($lastUpdate = $dateTool.getDate()) #set($ignore = $lastUpdate.setTime($event.getLong("lastUpdate"))) $device.name inactive from $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone) diff --git a/templates/short/deviceMoving.vm b/templates/short/deviceMoving.vm index 3307326d6..bf6aec340 100644 --- a/templates/short/deviceMoving.vm +++ b/templates/short/deviceMoving.vm @@ -1,2 +1,2 @@ -#set($title = "Moving") +#set($subject = "$device.name: moving") $device.name moving at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOffline.vm b/templates/short/deviceOffline.vm index 1967970b3..e663812ab 100644 --- a/templates/short/deviceOffline.vm +++ b/templates/short/deviceOffline.vm @@ -1,2 +1,2 @@ -#set($title = "Offline") +#set($subject = "$device.name: offline") $device.name offline at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOnline.vm b/templates/short/deviceOnline.vm index 65a59a8b3..bf3b40096 100644 --- a/templates/short/deviceOnline.vm +++ b/templates/short/deviceOnline.vm @@ -1,2 +1,2 @@ -#set($title = "Online") +#set($subject = "$device.name: online") $device.name online at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOverspeed.vm b/templates/short/deviceOverspeed.vm index fa4d7b189..849c6ddb7 100644 --- a/templates/short/deviceOverspeed.vm +++ b/templates/short/deviceOverspeed.vm @@ -1,3 +1,4 @@ +#set($subject = "$device.name: exceeds the speed") #if($speedUnit == 'kmh') #set($speedValue = $position.speed * 1.852) #set($speedString = $numberTool.format("0.0 km/h", $speedValue)) @@ -7,5 +8,4 @@ #else #set($speedString = $numberTool.format("0.0 kn", $position.speed)) #end -#set($title = "Overspeed") $device.name exceeds the speed $speedString#{if}($geofence) in $geofence.name#{else}#{end} at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceStopped.vm b/templates/short/deviceStopped.vm index 42147782b..8fabf89f1 100644 --- a/templates/short/deviceStopped.vm +++ b/templates/short/deviceStopped.vm @@ -1,2 +1,2 @@ -#set($title = "Stopped") +#set($subject = "$device.name: stopped") $device.name stopped at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceUnknown.vm b/templates/short/deviceUnknown.vm index b0fd2c42d..b6a6e9c9f 100644 --- a/templates/short/deviceUnknown.vm +++ b/templates/short/deviceUnknown.vm @@ -1,2 +1,2 @@ -#set($title = "Status unknown") +#set($subject = "$device.name: status is unknown") $device.name status is unknown at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/driverChanged.vm b/templates/short/driverChanged.vm index fc9a6689e..df96b00a1 100644 --- a/templates/short/driverChanged.vm +++ b/templates/short/driverChanged.vm @@ -1,7 +1,7 @@ +#set($subject = "$device.name: driver has changed") #if($driver) #set($driverName = $driver.name) #else #set($driverName = $event.getString("driverUniqueId")) #end -#set($title = "Driver changed") Driver $driverName has changed in $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceEnter.vm b/templates/short/geofenceEnter.vm index 79736b096..8c250665e 100644 --- a/templates/short/geofenceEnter.vm +++ b/templates/short/geofenceEnter.vm @@ -1,2 +1,2 @@ -#set($title = "Geofence entered") +#set($subject = "$device.name: has entered geofence") $device.name has entered geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceExit.vm b/templates/short/geofenceExit.vm index db5243600..7d3ae6f6e 100644 --- a/templates/short/geofenceExit.vm +++ b/templates/short/geofenceExit.vm @@ -1,2 +1,2 @@ -#set($title = "Geofence exited") +#set($subject = "$device.name: has exited geofence") $device.name has exited geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOff.vm b/templates/short/ignitionOff.vm index 953e8d0a5..db5a3f3e1 100644 --- a/templates/short/ignitionOff.vm +++ b/templates/short/ignitionOff.vm @@ -1,2 +1,2 @@ -#set($title = "Ignition OFF") +#set($subject = "$device.name: ignition OFF") $device.name ignition OFF at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOn.vm b/templates/short/ignitionOn.vm index 610b8e272..412ad4d84 100644 --- a/templates/short/ignitionOn.vm +++ b/templates/short/ignitionOn.vm @@ -1,2 +1,2 @@ -#set($title = "Ignition ON") +#set($subject = "$device.name: ignition ON") $device.name ignition ON at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/maintenance.vm b/templates/short/maintenance.vm index 917345599..a58e274b8 100644 --- a/templates/short/maintenance.vm +++ b/templates/short/maintenance.vm @@ -1,2 +1,2 @@ -#set($title = "Maintenance") +#set($subject = "$device.name: maintenance is required") $device.name maintenance $maintenance.name is required at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/test.vm b/templates/short/test.vm index bd317d97b..c9d93ce67 100644 --- a/templates/short/test.vm +++ b/templates/short/test.vm @@ -1,2 +1,2 @@ -#set($title = "Test") +#set($subject = "Test message") Test message diff --git a/templates/short/textMessage.vm b/templates/short/textMessage.vm index 456dcacd3..54c134df4 100644 --- a/templates/short/textMessage.vm +++ b/templates/short/textMessage.vm @@ -1,2 +1,2 @@ -#set($title = "Text message") +#set($subject = "$device.name: text message received") Text message received from $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/unknown.vm b/templates/short/unknown.vm index a7259f6e9..2f9d5e3af 100644 --- a/templates/short/unknown.vm +++ b/templates/short/unknown.vm @@ -1,2 +1,2 @@ -#set($title = "Unknown") +#set($subject = "Unknown type") Unknown type -- cgit v1.2.3 From b563ec10b48742f34fe9f9738b0b4ce5967d0fe6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Nov 2021 22:53:16 -0700 Subject: Decode acceleration data --- .../traccar/protocol/HuabaoProtocolDecoder.java | 33 ++++++++++++++++++++++ .../protocol/HuabaoProtocolDecoderTest.java | 3 ++ 2 files changed, 36 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 05411addf..3c01c0468 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -53,6 +53,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TERMINAL_CONTROL = 0x8105; public static final int MSG_TERMINAL_AUTH = 0x0102; public static final int MSG_LOCATION_REPORT = 0x0200; + public static final int MSG_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; @@ -136,6 +137,11 @@ 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 { @@ -216,6 +222,33 @@ 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; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 07442fbef..bf94c5dc5 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyNotNull(decoder, binary( + "7e207002940121523001530047210927151009000e002d80ac210927151010000e002d80ab210927151011000e002d80ac210927151012000e002e80ab210927151013000e002d80ab210927151014000e002d80ab210927151015000e002d80ab210927151016000e002d80aa210927151017000e002e80ab210927151018000e002d80ab210927151019000e002e80ac210927151020000e002d80ab210927151021000e002d80ab210927151022000d002d80ac210927151023000e002d80ac210927151024000e002e80ab210927151025000e002e80b0210927151026000e002e80ab210927151027000e002d80ab210927151028000e002e80b0210927151029000e002d80b0210927151030000e002e80ab210927151031000e002d80ab210927151032000e002d80aa210927151033000e002d80ab210927151034000e002d80ab210927151035000e002d80ab210927151036000e002d80ab210927151037000e002d80ab210927151038000e002d80b0210927151039000d002e80aa210927151040000e002d80ab210927151041000e002d80a5210927151042000e002e80ab210927151043000e002d80aa210927151044000e002d80ab210927151045000e002d80ab210927151046000e002d80ac210927151047000e002e80ab210927151048000e002e80a5210927151049000e002d80ab210927151050000e002d80ab210927151051000e002d80ab210927151052000e002d80ab210927151053000e002d80aa210927151054000e002e80b0210927151055000e002e80ab210927151056000e002d80ac210927151057000e002e80ab210927151058000e002d80ab210927151059000e002e80ab210927151100000e002d80ab210927151101000e002e80aa210927151102000e002d80a6210927151103000e002e80a5847e")); + verifyNotNull(decoder, binary( "7e07040226046110426684002b000601005f0000000000000000000000000000000000000000000021031410530001040000000030011b310101e4020064e50101e60100e7080000000000000000eb2101cc00253510260100000000000000000000000000000000000000000000000000005f00000000004c0001000000000000000000000000000021031410531401040000000030011f310103e4020064e50101e60100e7080000000000000000eb2101cc0025351026012535100f32263d11f931000000000000000000000000000000005f00000000004c0001000000000000000000000000000021031410534001040000000030011f310104e4020064e50101e60100e7080000000000000000eb2101cc002535102601263d11f92d0000000000000000000000000000000000000000005f00000000004c00010000000000000000000000000000210314105350010400000000300118310104e4020064e50101e60100e7080000000000000000eb2101cc002535102601263d11f92e25350f6f2c263d120d2c00000000000000000000005f00000000004c0001000000000000000000000000000021031410540001040000000030011d310105e4020064e50101e60100e7080000000000000000eb2101cc002535102601263d11f93025350f6f2e263d120d2e00000000000000000000003c00000000004c0003015ae3e106c82ab900000010010b21031410540901040000000030011b310105e4020064e50101e60100e7080000000000000000f97e")); -- cgit v1.2.3 From 2c4b4cdd2e8c8c09bcbdc18dd9cbaeba5bd64ce7 Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Thu, 4 Nov 2021 09:56:42 +0100 Subject: formatting-reverted --- .../org/traccar/api/resource/PasswordResource.java | 6 ++-- .../java/org/traccar/notification/FullMessage.java | 36 ---------------------- .../notification/NotificationFormatter.java | 9 ++---- .../traccar/notification/NotificationMessage.java | 36 ++++++++++++++++++++++ .../org/traccar/notification/ShortMessage.java | 36 ---------------------- .../notification/TextTemplateFormatter.java | 17 ++-------- .../traccar/notificators/NotificatorFirebase.java | 7 ++--- .../org/traccar/notificators/NotificatorMail.java | 6 ++-- .../traccar/notificators/NotificatorPushover.java | 6 ++-- .../org/traccar/notificators/NotificatorSms.java | 6 ++-- .../traccar/notificators/NotificatorTelegram.java | 4 +-- templates/short/alarm.vm | 2 +- templates/short/commandResult.vm | 2 +- templates/short/deviceFuelDrop.vm | 2 +- templates/short/deviceInactive.vm | 2 +- templates/short/deviceMoving.vm | 2 +- templates/short/deviceOffline.vm | 2 +- templates/short/deviceOnline.vm | 2 +- templates/short/deviceOverspeed.vm | 2 +- templates/short/deviceStopped.vm | 2 +- templates/short/deviceUnknown.vm | 2 +- templates/short/driverChanged.vm | 2 +- templates/short/geofenceEnter.vm | 2 +- templates/short/geofenceExit.vm | 2 +- templates/short/ignitionOff.vm | 2 +- templates/short/ignitionOn.vm | 2 +- templates/short/maintenance.vm | 2 +- templates/short/test.vm | 2 +- templates/short/textMessage.vm | 2 +- templates/short/unknown.vm | 2 +- 30 files changed, 77 insertions(+), 130 deletions(-) delete mode 100644 src/main/java/org/traccar/notification/FullMessage.java create mode 100644 src/main/java/org/traccar/notification/NotificationMessage.java delete mode 100644 src/main/java/org/traccar/notification/ShortMessage.java diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 20e8d768d..74cb7ca34 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.FullMessage; +import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; import javax.annotation.security.PermitAll; @@ -53,8 +53,8 @@ public class PasswordResource extends BaseResource { Context.getUsersManager().updateItem(user); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); velocityContext.put("token", token); - FullMessage message = TextTemplateFormatter.formatFullMessage(velocityContext, "passwordReset"); - Context.getMailManager().sendMessage(userId, message.getSubject(), message.getBody()); + NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset","full"); + Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); break; } } diff --git a/src/main/java/org/traccar/notification/FullMessage.java b/src/main/java/org/traccar/notification/FullMessage.java deleted file mode 100644 index f66537c6e..000000000 --- a/src/main/java/org/traccar/notification/FullMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.notification; - -public class FullMessage { - - private String subject; - private String body; - - public FullMessage(String subject, String body) { - this.subject = subject; - this.body = body; - } - - public String getSubject() { - return subject; - } - - public String getBody() { - return body; - } -} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index f33961c8b..9a6723a71 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -58,14 +58,9 @@ public final class NotificationFormatter { return velocityContext; } - public static FullMessage formatFullMessage(long userId, Event event, Position position) { + public static NotificationMessage formatMessage(long userId, Event event, Position position, String templatePath) { VelocityContext velocityContext = prepareContext(userId, event, position); - return TextTemplateFormatter.formatFullMessage(velocityContext, event.getType()); - } - - public static ShortMessage formatShortMessage(long userId, Event event, Position position) { - VelocityContext velocityContext = prepareContext(userId, event, position); - return TextTemplateFormatter.formatShortMessage(velocityContext, event.getType()); + return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } } diff --git a/src/main/java/org/traccar/notification/NotificationMessage.java b/src/main/java/org/traccar/notification/NotificationMessage.java new file mode 100644 index 000000000..0fb8d7654 --- /dev/null +++ b/src/main/java/org/traccar/notification/NotificationMessage.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.notification; + +public class NotificationMessage { + + private String subject; + private String body; + + public NotificationMessage(String subject, String body) { + this.subject = subject; + this.body = body; + } + + public String getSubject() { + return subject; + } + + public String getBody() { + return body; + } +} diff --git a/src/main/java/org/traccar/notification/ShortMessage.java b/src/main/java/org/traccar/notification/ShortMessage.java deleted file mode 100644 index 28812a1f1..000000000 --- a/src/main/java/org/traccar/notification/ShortMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.notification; - -public class ShortMessage { - - private String title; - private String body; - - public ShortMessage(String title, String body) { - this.title = title; - this.body = body; - } - - public String getTitle() { - return title; - } - - public String getBody() { - return body; - } -} diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 8a4d35677..6a95628f0 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -71,22 +71,11 @@ public final class TextTemplateFormatter { return template; } - public static FullMessage formatFullMessage(VelocityContext velocityContext, String name) { - String formattedMessage = formatMessage(velocityContext, name, "full"); - return new FullMessage((String) velocityContext.get("subject"), formattedMessage); - } - - public static ShortMessage formatShortMessage(VelocityContext velocityContext, String name) { - String formattedMessage = formatMessage(velocityContext, name, "short"); - return new ShortMessage((String) velocityContext.get("title"), formattedMessage); - } - - private static String formatMessage( - VelocityContext velocityContext, String name, String templatePath) { - + public static NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { StringWriter writer = new StringWriter(); getTemplate(name, templatePath).merge(velocityContext, writer); - return writer.toString(); + String formattedMessage = writer.toString(); + return new NotificationMessage((String) velocityContext.get("subject"), formattedMessage); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 9d1982f9c..37d0cb25a 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -24,9 +24,8 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.FullMessage; +import org.traccar.notification.NotificationMessage; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -70,10 +69,10 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); Notification notification = new Notification(); - notification.title= shortMessage.getTitle(); + notification.title= shortMessage.getSubject(); notification.body = shortMessage.getBody(); notification.sound = "default"; diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 6b9774c58..48e9d2311 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.FullMessage; +import org.traccar.notification.NotificationMessage; 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 { - FullMessage message = NotificationFormatter.formatFullMessage(userId, event, position); - Context.getMailManager().sendMessage(userId, message.getSubject(), message.getBody()); + NotificationMessage fullMessage = NotificationFormatter.formatMessage(userId, event, position,"full"); + Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index e541ea525..b62be7654 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,7 +24,7 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; +import org.traccar.notification.NotificationMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -77,13 +77,13 @@ public class NotificatorPushover extends Notificator { return; } - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + 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.getTitle(); + message.title= shortMessage.getSubject(); message.message = shortMessage.getBody(); Context.getClient().target(url).request() diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 360eb44ff..c99b555ce 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -24,7 +24,7 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; +import org.traccar.notification.NotificationMessage; public final class NotificatorSms extends Notificator { @@ -32,7 +32,7 @@ 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) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -43,7 +43,7 @@ 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) { - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a8cdacfbf..62a5a14ff 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,7 +25,7 @@ import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.ShortMessage; +import org.traccar.notification.NotificationMessage; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -99,7 +99,7 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - ShortMessage shortMessage = NotificationFormatter.formatShortMessage(userId, event, position); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/templates/short/alarm.vm b/templates/short/alarm.vm index faab92291..15970dab8 100644 --- a/templates/short/alarm.vm +++ b/templates/short/alarm.vm @@ -1,2 +1,2 @@ -#set($title = "Alarm") +#set($subject = "$device.name: alarm!") $device.name alarm: $position.getString("alarm") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/commandResult.vm b/templates/short/commandResult.vm index 7b3986573..6dc7a5dec 100644 --- a/templates/short/commandResult.vm +++ b/templates/short/commandResult.vm @@ -1,2 +1,2 @@ -#set($title = "Command Result") +#set($subject = "$device.name: command result received") $device.name command result received: $position.getString("result") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceFuelDrop.vm b/templates/short/deviceFuelDrop.vm index 2a4d2c608..babe14351 100644 --- a/templates/short/deviceFuelDrop.vm +++ b/templates/short/deviceFuelDrop.vm @@ -1,2 +1,2 @@ -#set($title = "Fuel Drop") +#set($subject = "$device.name: fuel drop") $device.name fuel drop at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceInactive.vm b/templates/short/deviceInactive.vm index f701ba408..c293bf1b2 100644 --- a/templates/short/deviceInactive.vm +++ b/templates/short/deviceInactive.vm @@ -1,4 +1,4 @@ -#set($title = "Inactive") +#set($subject = "$device.name: inactive") #set($lastUpdate = $dateTool.getDate()) #set($ignore = $lastUpdate.setTime($event.getLong("lastUpdate"))) $device.name inactive from $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone) diff --git a/templates/short/deviceMoving.vm b/templates/short/deviceMoving.vm index 3307326d6..bf6aec340 100644 --- a/templates/short/deviceMoving.vm +++ b/templates/short/deviceMoving.vm @@ -1,2 +1,2 @@ -#set($title = "Moving") +#set($subject = "$device.name: moving") $device.name moving at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOffline.vm b/templates/short/deviceOffline.vm index 1967970b3..e663812ab 100644 --- a/templates/short/deviceOffline.vm +++ b/templates/short/deviceOffline.vm @@ -1,2 +1,2 @@ -#set($title = "Offline") +#set($subject = "$device.name: offline") $device.name offline at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOnline.vm b/templates/short/deviceOnline.vm index 65a59a8b3..bf3b40096 100644 --- a/templates/short/deviceOnline.vm +++ b/templates/short/deviceOnline.vm @@ -1,2 +1,2 @@ -#set($title = "Online") +#set($subject = "$device.name: online") $device.name online at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceOverspeed.vm b/templates/short/deviceOverspeed.vm index fa4d7b189..849c6ddb7 100644 --- a/templates/short/deviceOverspeed.vm +++ b/templates/short/deviceOverspeed.vm @@ -1,3 +1,4 @@ +#set($subject = "$device.name: exceeds the speed") #if($speedUnit == 'kmh') #set($speedValue = $position.speed * 1.852) #set($speedString = $numberTool.format("0.0 km/h", $speedValue)) @@ -7,5 +8,4 @@ #else #set($speedString = $numberTool.format("0.0 kn", $position.speed)) #end -#set($title = "Overspeed") $device.name exceeds the speed $speedString#{if}($geofence) in $geofence.name#{else}#{end} at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceStopped.vm b/templates/short/deviceStopped.vm index 42147782b..8fabf89f1 100644 --- a/templates/short/deviceStopped.vm +++ b/templates/short/deviceStopped.vm @@ -1,2 +1,2 @@ -#set($title = "Stopped") +#set($subject = "$device.name: stopped") $device.name stopped at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/deviceUnknown.vm b/templates/short/deviceUnknown.vm index b0fd2c42d..b6a6e9c9f 100644 --- a/templates/short/deviceUnknown.vm +++ b/templates/short/deviceUnknown.vm @@ -1,2 +1,2 @@ -#set($title = "Status unknown") +#set($subject = "$device.name: status is unknown") $device.name status is unknown at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/driverChanged.vm b/templates/short/driverChanged.vm index fc9a6689e..df96b00a1 100644 --- a/templates/short/driverChanged.vm +++ b/templates/short/driverChanged.vm @@ -1,7 +1,7 @@ +#set($subject = "$device.name: driver has changed") #if($driver) #set($driverName = $driver.name) #else #set($driverName = $event.getString("driverUniqueId")) #end -#set($title = "Driver changed") Driver $driverName has changed in $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceEnter.vm b/templates/short/geofenceEnter.vm index 79736b096..8c250665e 100644 --- a/templates/short/geofenceEnter.vm +++ b/templates/short/geofenceEnter.vm @@ -1,2 +1,2 @@ -#set($title = "Geofence entered") +#set($subject = "$device.name: has entered geofence") $device.name has entered geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/geofenceExit.vm b/templates/short/geofenceExit.vm index db5243600..7d3ae6f6e 100644 --- a/templates/short/geofenceExit.vm +++ b/templates/short/geofenceExit.vm @@ -1,2 +1,2 @@ -#set($title = "Geofence exited") +#set($subject = "$device.name: has exited geofence") $device.name has exited geofence $geofence.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOff.vm b/templates/short/ignitionOff.vm index 953e8d0a5..db5a3f3e1 100644 --- a/templates/short/ignitionOff.vm +++ b/templates/short/ignitionOff.vm @@ -1,2 +1,2 @@ -#set($title = "Ignition OFF") +#set($subject = "$device.name: ignition OFF") $device.name ignition OFF at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/ignitionOn.vm b/templates/short/ignitionOn.vm index 610b8e272..412ad4d84 100644 --- a/templates/short/ignitionOn.vm +++ b/templates/short/ignitionOn.vm @@ -1,2 +1,2 @@ -#set($title = "Ignition ON") +#set($subject = "$device.name: ignition ON") $device.name ignition ON at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/maintenance.vm b/templates/short/maintenance.vm index 917345599..a58e274b8 100644 --- a/templates/short/maintenance.vm +++ b/templates/short/maintenance.vm @@ -1,2 +1,2 @@ -#set($title = "Maintenance") +#set($subject = "$device.name: maintenance is required") $device.name maintenance $maintenance.name is required at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/test.vm b/templates/short/test.vm index bd317d97b..c9d93ce67 100644 --- a/templates/short/test.vm +++ b/templates/short/test.vm @@ -1,2 +1,2 @@ -#set($title = "Test") +#set($subject = "Test message") Test message diff --git a/templates/short/textMessage.vm b/templates/short/textMessage.vm index 456dcacd3..54c134df4 100644 --- a/templates/short/textMessage.vm +++ b/templates/short/textMessage.vm @@ -1,2 +1,2 @@ -#set($title = "Text message") +#set($subject = "$device.name: text message received") Text message received from $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) diff --git a/templates/short/unknown.vm b/templates/short/unknown.vm index a7259f6e9..2f9d5e3af 100644 --- a/templates/short/unknown.vm +++ b/templates/short/unknown.vm @@ -1,2 +1,2 @@ -#set($title = "Unknown") +#set($subject = "Unknown type") Unknown type -- cgit v1.2.3 From f3b8aa2e7355ca7bf7a8cf8c60e703300361cfe1 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:31:21 +0100 Subject: Update src/main/java/org/traccar/notification/TextTemplateFormatter.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/notification/TextTemplateFormatter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 6a95628f0..b7058c824 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -74,8 +74,7 @@ public final class TextTemplateFormatter { public static NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { StringWriter writer = new StringWriter(); getTemplate(name, templatePath).merge(velocityContext, writer); - String formattedMessage = writer.toString(); - return new NotificationMessage((String) velocityContext.get("subject"), formattedMessage); + return new NotificationMessage((String) velocityContext.get("subject"), writer.toString()); } } -- cgit v1.2.3 From 8465c59b8e63fa42fdf0d5966a266f3d1775bef1 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:31:33 +0100 Subject: Update src/main/java/org/traccar/notificators/NotificatorFirebase.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 37d0cb25a..8951c8892 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -72,7 +72,7 @@ public class NotificatorFirebase extends Notificator { NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); Notification notification = new Notification(); - notification.title= shortMessage.getSubject(); + notification.title = shortMessage.getSubject(); notification.body = shortMessage.getBody(); notification.sound = "default"; -- cgit v1.2.3 From 0cb463258cf282036db6fdf3e08a50dc189a154b Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:31:41 +0100 Subject: Update src/main/java/org/traccar/notificators/NotificatorTelegram.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/notificators/NotificatorTelegram.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 62a5a14ff..70148110c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -99,7 +99,7 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); -- cgit v1.2.3 From 55f7d7ab29772267e49489993a978c4eb83f3fe4 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:31:48 +0100 Subject: Update src/main/java/org/traccar/api/resource/PasswordResource.java Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/api/resource/PasswordResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 74cb7ca34..79d675434 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -53,7 +53,7 @@ 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"); + NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); break; } -- cgit v1.2.3 From 7d5a18e6fd2b798873a719b361c9a7a61a236d6b Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Thu, 4 Nov 2021 21:03:48 +0100 Subject: Update NotificatorFirebase.java formatting-reverted --- .../org/traccar/notificators/NotificatorFirebase.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 8951c8892..b452205f6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -83,15 +83,15 @@ public class NotificatorFirebase extends Notificator { Context.getClient().target(url).request() .header("Authorization", "key=" + key) .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Firebase notification error", throwable); - } - }); + @Override + public void completed(Object o) { + } + + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Firebase notification error", throwable); + } + }); } } -- cgit v1.2.3 From 81836343161dfe5eb4aef1972a1e368686685fd6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 4 Nov 2021 22:11:52 -0700 Subject: Fix Teltonika DualCam issues --- src/main/java/org/traccar/protocol/DualcamProtocol.java | 2 +- src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index 9f8d6778e..04c4f2bd1 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -25,8 +25,8 @@ public class DualcamProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new DualcamFrameDecoder()); pipeline.addLast(new DualcamProtocolDecoder(DualcamProtocol.this)); - pipeline.addLast(new DishaProtocolDecoder(DualcamProtocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index 4647e287c..390b8e705 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -110,6 +110,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { response.writeShort(MSG_INIT_REQUEST); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } + return position; } else { currentPacket += 1; } -- cgit v1.2.3 From 54e0ed6aa3fb39c344a2aaf68eb0b03967e912ef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 4 Nov 2021 23:10:03 -0700 Subject: Fix photo decoding --- src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index 390b8e705..457b5ae62 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -93,7 +93,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { break; case MSG_DATA: buf.readUnsignedShort(); // length - photo.writeBytes(buf, buf.readableBytes()); + photo.writeBytes(buf, buf.readableBytes() - 2); if (currentPacket == packetCount) { deviceSession = getDeviceSession(channel, remoteAddress); Position position = new Position(getProtocolName()); -- cgit v1.2.3 From c370aa660d216980a0c8f52ca856b4116ff5ca23 Mon Sep 17 00:00:00 2001 From: Khaksar Weqar Date: Fri, 5 Nov 2021 09:04:44 +0100 Subject: resolved-gradle-check-errors --- src/main/java/org/traccar/api/resource/PasswordResource.java | 3 ++- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 2 +- src/main/java/org/traccar/notificators/NotificatorMail.java | 2 +- src/main/java/org/traccar/notificators/NotificatorPushover.java | 4 ++-- src/main/java/org/traccar/notificators/NotificatorSms.java | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 79d675434..1868a6191 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -53,7 +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"); + NotificationMessage fullMessage = + TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); break; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index b452205f6..f91ec25a0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -69,7 +69,7 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 48e9d2311..9b5637ed8 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -30,7 +30,7 @@ public final class NotificatorMail extends Notificator { @Override public void sendSync(long userId, Event event, Position position) throws MessageException { try { - NotificationMessage fullMessage = NotificationFormatter.formatMessage(userId, event, position,"full"); + NotificationMessage fullMessage = NotificationFormatter.formatMessage(userId, event, position, "full"); Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index b62be7654..456c2fe4f 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -77,13 +77,13 @@ public class NotificatorPushover extends Notificator { return; } - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); + 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.title = shortMessage.getSubject(); message.message = shortMessage.getBody(); Context.getClient().target(url).request() diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index c99b555ce..fb817b112 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -32,7 +32,7 @@ public final class NotificatorSms extends Notificator { public void sendAsync(long userId, Event event, Position position) { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -43,7 +43,7 @@ public final class NotificatorSms extends Notificator { public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position,"short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); -- cgit v1.2.3 From 479a2b6c938177d10c02ea3c4937d129de774776 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 5 Nov 2021 10:09:02 -0700 Subject: Relax regular expression (fix #4767) --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 1 + src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 65d295dc3..042518cb2 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -80,6 +80,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .expression("([^,]+)?,?") // temperature .groupEnd("?") .groupEnd("?") + .any() .compile(); private String decodeAlarm(int value) { diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 1fbe71988..5dd7059e2 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = new StartekProtocolDecoder(null); + verifyPosition(decoder, text( + "&&W149,865429043319537,000,0,,211103013512,A,22.679003,114.045085,16,1.1,0,271,76,109075,460|0|249F|000010C5,19,0000003E,00,00,0A57|0168|0000|0000,1,0100000C")); + verifyAttribute(decoder, text( "&&:23,860262050015424,129,OKA2"), Position.KEY_RESULT, "129,OK"); -- cgit v1.2.3 From f8e6bc5ced2244f5f09664e7d778c0bf51cd4ab9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 5 Nov 2021 10:17:06 -0700 Subject: Fix photo request --- src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index 457b5ae62..c64b8171f 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -64,18 +64,16 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); long settings = buf.readUnsignedInt(); if (channel != null && deviceSession != null) { - if (BitUtil.check(settings, 26)) { - ByteBuf response = Unpooled.buffer(); + ByteBuf response = Unpooled.buffer(); + if (BitUtil.between(settings, 26, 28) > 0) { response.writeShort(MSG_FILE_REQUEST); - String file = "%photof"; + String file = BitUtil.check(settings, 26) ? "%photof" : "%photor"; response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { - ByteBuf response = Unpooled.buffer(); response.writeShort(MSG_COMPLETE); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } break; case MSG_START: -- cgit v1.2.3 From 10a11e03fbb45506973c85ae49d0fd1443d0f9f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 5 Nov 2021 16:48:27 -0700 Subject: Support new Xexun protocol (fix #4727) --- setup/default.xml | 1 + src/main/java/org/traccar/helper/BufferUtil.java | 27 ++- .../org/traccar/protocol/Xexun2FrameDecoder.java | 69 +++++++ .../java/org/traccar/protocol/Xexun2Protocol.java | 34 ++++ .../traccar/protocol/Xexun2ProtocolDecoder.java | 205 +++++++++++++++++++++ .../traccar/protocol/Xexun2FrameDecoderTest.java | 19 ++ .../protocol/Xexun2ProtocolDecoderTest.java | 27 +++ 7 files changed, 373 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/Xexun2Protocol.java create mode 100644 src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 4d4de39b0..4e2a5f746 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -298,5 +298,6 @@ 5230 5231 5232 + 5233 diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index b086f0f9e..bbf12d738 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 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,19 +28,28 @@ public final class BufferUtil { } public static int indexOf(String needle, ByteBuf haystack) { - ByteBuf needleBuffer = Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII)); + 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)); try { - return ByteBufUtil.indexOf(needleBuffer, haystack); + return indexOf(wrappedNeedle, haystack, startIndex, endIndex); } finally { - needleBuffer.release(); + wrappedNeedle.release(); } } - 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); + 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); return result < 0 ? result : haystack.readerIndex() + startIndex + result; } diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java new file mode 100644 index 000000000..521d0209c --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2FrameDecoder.java @@ -0,0 +1,69 @@ +/* + * 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 new file mode 100644 index 000000000..265841c77 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -0,0 +1,34 @@ +/* + * 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 new file mode 100644 index 000000000..766a3f05b --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -0,0 +1,205 @@ +/* + * 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 lengths = new ArrayList<>(); + List 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; + } + +} diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java new file mode 100644 index 000000000..aeca95376 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Xexun2FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Xexun2FrameDecoder(); + + verifyFrame( + binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), + decoder.decode(null, null, binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java new file mode 100644 index 000000000..89c499016 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -0,0 +1,27 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Xexun2ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Xexun2ProtocolDecoder(null); + + verifyPositions(decoder, false, binary( + "FAAF00140004863921033475388000AFB7D203003800380038F9608A7B801E0060820205788A205DF523D97844FDB90443D37844FDB90465CFB4FBF946B0E8CEF639095803F8CC00000002350000004000FA608A7BA81E0060820205788A205DF523D97844FDB90443D2F639095803F8CFB4FBF946B0E8CE7844FDB90465CD00000002350000004000FB608A7BD01E0060820205788A205DF523D97844FDB90443D2F639095803F8CFB4FBF946B0E8CE7844FDB90465CD00000002350000004000FAAF")); + + verifyPositions(decoder, false, binary( + "faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf")); + + verifyPositions(decoder, false, binary( + "FAAF0014000486188105421927500035E6D2010032FC60EC264D00002003000000020205444E6DD72699D674427F7712CBC3BCF2AFD910BAC1C6FBE474CFC7A9B4FBE474CFC7A6FAAF")); + + verifyPositions(decoder, binary( + "FAAF00140CF18626490454584530002BF2DD0200130013D360EFD7F514006402010D46322C4A450BA026D460EFD7FA14006402010D46322C4A450BA026FAAF")); + + } + +} -- cgit v1.2.3 From f78da0d7ead0e445f129eac486cc468bedff7c73 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 5 Nov 2021 22:32:05 -0700 Subject: Extend Mobilogix protocol support --- .../traccar/protocol/MobilogixProtocolDecoder.java | 57 ++++++++++++++++++---- .../protocol/MobilogixProtocolDecoderTest.java | 5 +- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index ba70a8884..7947d0c26 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -40,11 +40,13 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .number("(dddd)-(dd)-(dd) ") // date (yyyymmdd) .number("(dd):(dd):(dd),") // time (hhmmss) .number("Td+,") // type - .number("d+,") // device type + .number("(d),") // archive .expression("[^,]+,") // protocol version .expression("([^,]+),") // serial number .number("(xx),") // status - .number("(d+.d+),") // battery + .number("(d+.d+)") // battery + .groupBegin() + .text(",") .number("(d)") // valid .number("(d)") // rssi .number("(d),") // satellites @@ -52,9 +54,31 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .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 { @@ -80,7 +104,10 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - position.setTime(parser.nextDateTime()); + position.setDeviceTime(parser.nextDateTime()); + if (parser.nextInt() == 0) { + position.set(Position.KEY_ARCHIVE, true); + } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { @@ -89,6 +116,7 @@ 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)); @@ -97,15 +125,24 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.setValid(parser.nextInt() > 0); + if (parser.hasNext(7)) { + + position.setValid(parser.nextInt() > 0); + position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + } else { + + getLastLocation(position, position.getDeviceTime()); + + } return position; } diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index efa46b9f6..aca6b9f29 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { var decoder = new MobilogixProtocolDecoder(null); + verifyAttributes(decoder, text( + "[2021-08-20 19:27:14,T14,1,V1.3.5,201909000982,53,12.18")); + verifyNull(decoder, text( "[2020-12-01 14:00:22,T1,1,V1.1.1,201951132031,,,12345678,724108005415815,359366080211420")); @@ -29,7 +32,7 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "[2021-10-25 20:54:11,T12,1,V1.2.3,201951132044,3F,9.23,991,-25.909262,-47.045387,1,341")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "[2021-10-25 20:48:14,T14,1,V1.2.3,201951132044,51,0.50")); verifyPosition(decoder, text( -- cgit v1.2.3 From 965ef9eb530963e71ce33c2a06af389c78192b51 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 11 Nov 2021 20:23:08 -0800 Subject: Handle new lines --- src/main/java/org/traccar/protocol/MobilogixProtocol.java | 4 ++-- src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index ebf2c9c7f..28380a2af 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 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 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. @@ -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, "]\r\n", "]")); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); 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 7947d0c26..f3b70e40c 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 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 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. @@ -83,7 +83,7 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = (String) msg; + String sentence = ((String) msg).trim(); String type = sentence.substring(21, sentence.indexOf(',', 21)); if (channel != null) { diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index aca6b9f29..ddfa6ad8b 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "[2021-08-20 19:27:14,T14,1,V1.3.5,201909000982,53,12.18")); + verifyAttributes(decoder, text( + "\r\n[2021-08-20 19:27:14,T14,1,V1.3.5,201909000982,53,12.18")); + verifyNull(decoder, text( "[2020-12-01 14:00:22,T1,1,V1.1.1,201951132031,,,12345678,724108005415815,359366080211420")); -- cgit v1.2.3 From 113f9a7a1295eb84174c40cb7f4bed61bdec2423 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 11 Nov 2021 20:30:10 -0800 Subject: Add test case --- src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 5dd7059e2..5d22344fa 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = new StartekProtocolDecoder(null); + verifyPosition(decoder, text( + "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); + verifyPosition(decoder, text( "&&W149,865429043319537,000,0,,211103013512,A,22.679003,114.045085,16,1.1,0,271,76,109075,460|0|249F|000010C5,19,0000003E,00,00,0A57|0168|0000|0000,1,0100000C")); -- cgit v1.2.3 From ee709450564299831dc90e648f6f11bb9e19b6d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 11 Nov 2021 20:44:24 -0800 Subject: Support new GT06 variation --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 18 ++++++++++-------- .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 45218aba2..0dcdab892 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_LBS = 0x11; + public static final int MSG_GPS_LBS_6 = 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; @@ -124,6 +124,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { 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: @@ -141,13 +142,13 @@ 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: @@ -275,7 +276,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeLbs(Position position, ByteBuf buf, boolean hasLength) { + private boolean decodeLbs(Position position, ByteBuf buf, int type, boolean hasLength) { int length = 0; if (hasLength) { @@ -296,10 +297,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); + 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(); - position.setNetwork(new Network(CellTower.from( - BitUtil.to(mcc, 15), mnc, buf.readUnsignedShort(), buf.readUnsignedMedium()))); + position.setNetwork(new Network(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid))); if (length > 9) { buf.skipBytes(length - 9); @@ -885,7 +887,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); + decodeLbs(position, buf, type, hasStatus(type)); } if (hasStatus(type)) { @@ -1053,7 +1055,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } - if (decodeLbs(position, buf, true)) { + if (decodeLbs(position, buf, type, true)) { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 3caba32e6..d2d090c04 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "78782111150b0b022c30c804b7af7808810cb0003c00012e02d075df0084890c000679950d0a")); + verifyNotNull(decoder, binary( "797900377000000001020035000103002c0004616219d00043000b013601048153931500001a0001000808652820400643521000000101004e46760d0a")); -- cgit v1.2.3 From 148b251ff1c129b4b8c8038a47e1dc55a05e6f5d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 11 Nov 2021 21:15:03 -0800 Subject: New protocol variation --- .../traccar/protocol/MeitrackProtocolDecoder.java | 108 +++++++++++++-------- .../protocol/MeitrackProtocolDecoderTest.java | 3 + 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 9b12f1c15..5eab10498 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -68,15 +68,23 @@ 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 @@ -174,51 +182,65 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextInt()); position.set("runtime", parser.next()); - position.setNetwork(new Network(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi))); + 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))); + } position.set(Position.KEY_INPUT, parser.nextHexInt()); position.set(Position.KEY_OUTPUT, parser.nextHexInt()); - for (int i = 1; i <= 3; i++) { - position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); - } + 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()); + } + + 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 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/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 3f0e5b2d3..58861c139 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = new MeitrackProtocolDecoder(null); + verifyPosition(decoder, buffer( + "$$D149,867047043162018,AAA,35,-1.264865,36.800705,211001105240,A,9,20,41.0,323,1,1697,1,0,000|00||,0000,4.33|12.96|1.92|2.72|2.69,0.000000|0|0.000000,*E1")); + verifyPositions(decoder, binary( "2424413132332c3836313538353034333230303836322c4343452c010000000100590015000305010609071b0b081c000939010a07000b1700199e011a9505921a0099c4089c5500c93e00405a000602a8b114000343f12e0604d18806270c654a2e000da20537009bb8963904010e0c0d020300aa7a0af69e0100002a35340d0a")); -- cgit v1.2.3 From 220a9fa8d05cd0e0d1459e6da852c82e0412d163 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Nov 2021 21:52:12 -0800 Subject: Decode location type --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 3c01c0468..871410c44 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -501,11 +501,15 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { List positions = new LinkedList<>(); int count = buf.readUnsignedShort(); - buf.readUnsignedByte(); // location type + int locationType = buf.readUnsignedByte(); for (int i = 0; i < count; i++) { int endIndex = buf.readUnsignedShort() + buf.readerIndex(); - positions.add(decodeLocation(deviceSession, buf)); + Position position = decodeLocation(deviceSession, buf); + if (locationType == 0) { + position.set(Position.KEY_ARCHIVE, true); + } + positions.add(position); buf.readerIndex(endIndex); } -- cgit v1.2.3 From f0f22ee3e7f038a570800df10f1f29bb49a1a379 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Nov 2021 10:09:37 -0800 Subject: Support vibration alarm --- .../java/org/traccar/protocol/TopinProtocolDecoder.java | 14 ++++++++++++++ .../org/traccar/protocol/TopinProtocolDecoderTest.java | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 87db95946..7fd939caa 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -51,6 +51,9 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_WIFI_OFFLINE = 0x17; public static final int MSG_TIME_UPDATE = 0x30; 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) { @@ -250,6 +253,17 @@ 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/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index 8f5b5ebbb..331be974c 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class TopinProtocolDecoderTest extends ProtocolTest { @@ -16,6 +17,10 @@ public class TopinProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780d0103593390754169634d0d0a")); + verifyAttribute(decoder, binary( + "787801940D0A"), + Position.KEY_ALARM, Position.ALARM_VIBRATION); + verifyAttributes(decoder, binary( "78780A13424008196400041F000D0A")); -- cgit v1.2.3 From 33f20c440ee2a132c222781c4197dff10ecc6b3c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Nov 2021 10:26:56 -0800 Subject: Add Topin protocol encoder --- .../java/org/traccar/protocol/TopinProtocol.java | 6 +- .../org/traccar/protocol/TopinProtocolDecoder.java | 1 + .../org/traccar/protocol/TopinProtocolEncoder.java | 66 ++++++++++++++++++++++ .../traccar/protocol/TopinProtocolEncoderTest.java | 24 ++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/traccar/protocol/TopinProtocolEncoder.java create mode 100644 src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index 844dd7518..d28afbf94 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 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 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. @@ -18,13 +18,17 @@ 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 7fd939caa..267bce562 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -50,6 +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; diff --git a/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java b/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java new file mode 100644 index 000000000..77f80b9d4 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java @@ -0,0 +1,66 @@ +/* + * 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/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java new file mode 100644 index 000000000..d3ff13941 --- /dev/null +++ b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class TopinProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + var encoder = new TopinProtocolEncoder(null); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_SOS_NUMBER); + command.set(Command.KEY_INDEX, 1); + command.set(Command.KEY_PHONE, "13533333333"); + + verifyCommand(encoder, command, binary("78780C4131333533333333333333330D0A")); + + } + +} -- cgit v1.2.3 From 7ce7c73a2461ac3b2dde98398a4458e86cfa89bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 Nov 2021 16:16:37 -0800 Subject: Support Cruz Techo protocol --- setup/default.xml | 1 + .../org/traccar/protocol/CruzTechoProtocol.java | 39 ++++++++ .../traccar/protocol/CruzTechoProtocolDecoder.java | 108 +++++++++++++++++++++ .../protocol/CruzTechoProtocolDecoderTest.java | 18 ++++ 4 files changed, 166 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/CruzTechoProtocol.java create mode 100644 src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 4e2a5f746..d691bec62 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -299,5 +299,6 @@ 5231 5232 5233 + 5234 diff --git a/src/main/java/org/traccar/protocol/CruzTechoProtocol.java b/src/main/java/org/traccar/protocol/CruzTechoProtocol.java new file mode 100644 index 000000000..da54e118a --- /dev/null +++ b/src/main/java/org/traccar/protocol/CruzTechoProtocol.java @@ -0,0 +1,39 @@ +/* + * 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 io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class CruzTechoProtocol extends BaseProtocol { + + public CruzTechoProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new CruzTechoProtocolDecoder(CruzTechoProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java b/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java new file mode 100644 index 000000000..9809fa5a8 --- /dev/null +++ b/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java @@ -0,0 +1,108 @@ +/* + * 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 CruzTechoProtocolDecoder extends BaseProtocolDecoder { + + public CruzTechoProtocolDecoder(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/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java new file mode 100644 index 000000000..3dfe9ef62 --- /dev/null +++ b/src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class CruzTechoProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new CruzTechoProtocolDecoder(null); + + verifyPosition(decoder, text( + "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); + + } + +} -- cgit v1.2.3 From 88e5b090d7a71255a29fe6ad2ae1525c1c0a03be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 Nov 2021 16:28:57 -0800 Subject: Rename protocol to Techto Cruz --- setup/default.xml | 2 +- .../org/traccar/protocol/CruzTechoProtocol.java | 39 -------- .../traccar/protocol/CruzTechoProtocolDecoder.java | 108 --------------------- .../org/traccar/protocol/TechtoCruzProtocol.java | 39 ++++++++ .../protocol/TechtoCruzProtocolDecoder.java | 108 +++++++++++++++++++++ .../protocol/CruzTechoProtocolDecoderTest.java | 18 ---- .../protocol/TechtoCruzProtocolDecoderTest.java | 18 ++++ 7 files changed, 166 insertions(+), 166 deletions(-) delete mode 100644 src/main/java/org/traccar/protocol/CruzTechoProtocol.java delete mode 100644 src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java create mode 100644 src/main/java/org/traccar/protocol/TechtoCruzProtocol.java create mode 100644 src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java delete mode 100644 src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java create mode 100644 src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index d691bec62..f314413f1 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -299,6 +299,6 @@ 5231 5232 5233 - 5234 + 5234 diff --git a/src/main/java/org/traccar/protocol/CruzTechoProtocol.java b/src/main/java/org/traccar/protocol/CruzTechoProtocol.java deleted file mode 100644 index da54e118a..000000000 --- a/src/main/java/org/traccar/protocol/CruzTechoProtocol.java +++ /dev/null @@ -1,39 +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 io.netty.handler.codec.string.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class CruzTechoProtocol extends BaseProtocol { - - public CruzTechoProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new CruzTechoProtocolDecoder(CruzTechoProtocol.this)); - } - }); - } - -} diff --git a/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java b/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.java deleted file mode 100644 index 9809fa5a8..000000000 --- a/src/main/java/org/traccar/protocol/CruzTechoProtocolDecoder.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 CruzTechoProtocolDecoder extends BaseProtocolDecoder { - - public CruzTechoProtocolDecoder(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/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java new file mode 100644 index 000000000..890a8abb1 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -0,0 +1,39 @@ +/* + * 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 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 LineBasedFrameDecoder(1024)); + 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 new file mode 100644 index 000000000..6b9f0edb6 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java @@ -0,0 +1,108 @@ +/* + * 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/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java deleted file mode 100644 index 3dfe9ef62..000000000 --- a/src/test/java/org/traccar/protocol/CruzTechoProtocolDecoderTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - -public class CruzTechoProtocolDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - var decoder = new CruzTechoProtocolDecoder(null); - - verifyPosition(decoder, text( - "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); - - } - -} diff --git a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java new file mode 100644 index 000000000..8f4a7915d --- /dev/null +++ b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TechtoCruzProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new TechtoCruzProtocolDecoder(null); + + verifyPosition(decoder, text( + "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); + + } + +} -- cgit v1.2.3 From a425ea42de76ba81890fb52b1f06eff82bba1ded Mon Sep 17 00:00:00 2001 From: casswarry0 Date: Sun, 21 Nov 2021 10:41:19 -0700 Subject: Changes to POSITION data type according to eeLink Device Protocol V2.2 (A4) added --- src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 613710587..3e805097c 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -218,6 +218,17 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } + if (BitUtil.check(flags, 7)) { + buf.readUnsignedByte(); // rat + short noc = buf.readUnsignedByte(); // noc + if (noc > 0) { + buf.skipBytes(19); // lte-srv + for (short i = 1; i < noc; i++) { + buf.skipBytes(5); // lte-nbr + } + } + } + if (type == MSG_WARNING) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); -- cgit v1.2.3 From 45690f44c55d5a6d0efc4d80a39f10578ff7e799 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Nov 2021 16:40:12 -0800 Subject: Fix tags decoding --- .../org/traccar/protocol/Minifinder2ProtocolDecoder.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 059041d6b..641a45864 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -124,6 +124,14 @@ 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 { @@ -214,7 +222,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { } break; case 0x23: - position.set("tagId", ByteBufUtil.hexDump(buf.readSlice(6))); + position.set("tagId", readTagId(buf)); position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); position.setValid(true); @@ -228,9 +236,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { break; case 0x28: int beaconFlags = buf.readUnsignedByte(); - position.set("tagId", ByteBufUtil.hexDump(buf.readSlice(6))); - position.set("tagRssi", buf.readUnsignedByte()); - buf.readUnsignedByte(); // 1m rssi + position.set("tagId", readTagId(buf)); + position.set("tagRssi", (int) buf.readByte()); + position.set("tag1mRssi", (int) buf.readByte()); if (BitUtil.check(beaconFlags, 7)) { position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); -- cgit v1.2.3 From 24f0197f32cee9f8951a9537123de6b5bbd4143f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Nov 2021 16:47:26 -0800 Subject: Add missing photo response --- .../org/traccar/protocol/GalileoProtocolDecoder.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index dc558147a..f29fb9850 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -309,18 +309,17 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { Position position = null; - if (length > 1) { + if (photo == null) { + photo = Unpooled.buffer(); + } - if (photo == null) { - photo = Unpooled.buffer(); - } + buf.readUnsignedByte(); // part number - buf.readUnsignedByte(); // part number - photo.writeBytes(buf, length - 1); + if (length > 1) { - sendResponse(channel, 0x07, buf.readUnsignedShortLE()); + photo.writeBytes(buf, length - 1); - } else if (photo != null) { + } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); @@ -336,6 +335,8 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } + sendResponse(channel, 0x07, buf.readUnsignedShortLE()); + return position; } -- cgit v1.2.3 From c0b26fd74ecb86f67c682da21a694665be2c5279 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Nov 2021 20:33:39 -0800 Subject: Handle values as strings --- .../org/traccar/protocol/StbProtocolDecoder.java | 31 +++++++++------------- .../traccar/protocol/StbProtocolDecoderTest.java | 4 +-- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index bd151c604..cc985d605 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -26,9 +26,7 @@ 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; @@ -97,39 +95,34 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { String id = propertyObject.getString("id"); switch (id) { case "01101001": - locationType = propertyObject.getInt("value"); + locationType = Integer.parseInt(propertyObject.getString("value")); break; case "01102001": - position.setLongitude(propertyObject.getJsonNumber("value").doubleValue()); + position.setLongitude( + Double.parseDouble(propertyObject.getString("value"))); break; case "01103001": - position.setLatitude(propertyObject.getJsonNumber("value").doubleValue()); + position.setLatitude( + Double.parseDouble(propertyObject.getString("value"))); break; case "01118001": - position.set(Position.KEY_DEVICE_TEMP, propertyObject.getJsonNumber("value").doubleValue()); + position.set( + Position.KEY_DEVICE_TEMP, Double.parseDouble(propertyObject.getString("value"))); break; case "01122001": - position.set("batteryControl", propertyObject.getInt("value")); + position.set( + "batteryControl", Integer.parseInt(propertyObject.getString("value"))); break; case "02301001": - position.set("switchCabinetCommand", propertyObject.getInt("value")); + position.set( + "switchCabinetCommand", Integer.parseInt(propertyObject.getString("value"))); break; default: String key = "id" + id; if (propertyObject.containsKey("doorId")) { key += "Door" + propertyObject.getString("doorId"); } - 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; - } + position.set(key, propertyObject.getString("value")); break; } } diff --git a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java index 5e351c19f..74b30f9eb 100644 --- a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java @@ -10,8 +10,8 @@ public class StbProtocolDecoderTest extends ProtocolTest { var decoder = new StbProtocolDecoder(null); - verifyPosition(decoder, text( - "{\"msgType\":310,\"attrList\":[{\"id\":\"01106001\",\"value\":31},{\"id\":\"01101001\",\"value\":1},{\"id\":\"01102001\",\"value\":113.826355},{\"id\":\"01103001\",\"value\":22.846399}],\"devId\":\"BT106001020JPZZ210718001\",\"txnNo\":\"1626940074000\"}")); + verifyAttributes(decoder, text( + "{\"attrList\":[{\"id\":\"02101001\",\"value\":\"510101051161205774\"},{\"id\":\"02105001\",\"value\":\"-61\"},{\"id\":\"02102001\",\"value\":\"1\"},{\"doorId\":\"1\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"1\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"2\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"2\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"3\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"3\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"4\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"4\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"5\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"5\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"6\",\"id\":\"02104001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02106001\",\"value\":\"BT106002320JPZZ210718002\"},{\"doorId\":\"6\",\"id\":\"02109001\",\"value\":\"98\"},{\"doorId\":\"6\",\"id\":\"02110001\",\"value\":\"100\"},{\"doorId\":\"6\",\"id\":\"01118001\",\"value\":\"27\"},{\"doorId\":\"6\",\"id\":\"01119001\",\"value\":\"26\"},{\"doorId\":\"6\",\"id\":\"01120001\",\"value\":\"28\"},{\"doorId\":\"6\",\"id\":\"02114001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02116001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02117001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01121001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02130001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01122001\",\"value\":\"4\"},{\"doorId\":\"6\",\"id\":\"02001001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"02002001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"01116001\",\"value\":\"20\"},{\"doorId\":\"6\",\"id\":\"01117001\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117002\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117003\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117004\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117005\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117006\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117007\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117008\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117009\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117010\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117011\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117012\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117013\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117014\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117015\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117016\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117017\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117018\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117019\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117020\",\"value\":\"3323\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02103001\",\"value\":\"1\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"7\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"7\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"8\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"8\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02118001\",\"value\":\"1\"},{\"id\":\"02111001\",\"value\":\"0.0\"},{\"id\":\"02112001\",\"value\":\"0.0\"},{\"id\":\"02107001\",\"value\":\"229.1\"},{\"id\":\"02108001\",\"value\":\"1.005\"},{\"id\":\"02120001\",\"value\":\"143.76\"},{\"id\":\"02113001\",\"value\":\"29\"},{\"id\":\"02119001\",\"value\":\"1\"}],\"devId\":\"CHZD08KPD0210425046\",\"isFull\":1,\"msgType\":310,\"txnNo\":\"1636707944778\"}")); verifyAttributes(decoder, text( "{\"attrList\":[{\"doorId\":\"4\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"2\",\"id\":\"02103001\",\"value\":\"0\"},{\"id\":\"02120001\",\"value\":\"11.37\"},{\"doorId\":\"6\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"5\",\"id\":\"02103001\",\"value\":\"0\"},{\"id\":\"02105001\",\"value\":\"-150\"},{\"id\":\"02102001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"5\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"1\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"7\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02106001\",\"value\":\"\"},{\"id\":\"02101001\",\"value\":\"\"},{\"id\":\"02119001\",\"value\":\"1\"},{\"doorId\":\"6\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02106001\",\"value\":\"\"},{\"id\":\"02108001\",\"value\":\"0.922\"},{\"doorId\":\"2\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"4\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"3\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"8\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"1\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"7\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"8\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"4\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"8\",\"id\":\"02106001\",\"value\":\"\"},{\"id\":\"02112001\",\"value\":\"0.0\"},{\"doorId\":\"4\",\"id\":\"02104001\",\"value\":\"0\"},{\"id\":\"02111001\",\"value\":\"0.0\"},{\"id\":\"02113001\",\"value\":\"27\"},{\"doorId\":\"5\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02118001\",\"value\":\"1\"},{\"id\":\"02107001\",\"value\":\"229.7\"}],\"devId\":\"CHZD08KPD0210425046\",\"isFull\":0,\"msgType\":310,\"txnNo\":\"1626153841985\"}")); -- cgit v1.2.3 From fd47e69b388b1e0af8aa5ead940773f6b2da3e81 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Nov 2021 21:06:37 -0800 Subject: Decode IO values --- src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java index e882c2378..d509b3ec0 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java @@ -101,6 +101,10 @@ 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); } -- cgit v1.2.3 From 17370d68fe7383226d1d23a967985e9da4153601 Mon Sep 17 00:00:00 2001 From: casswarry0 Date: Tue, 23 Nov 2021 10:39:19 -0700 Subject: Revert changes to POSITION data type. Fix error with protocol version reporting from Traccar server to eeLink device to prevent eeLink device from sending LTE cell info. --- .../java/org/traccar/protocol/EelinkProtocolDecoder.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 3e805097c..8fe12fe69 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -218,17 +218,6 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } - if (BitUtil.check(flags, 7)) { - buf.readUnsignedByte(); // rat - short noc = buf.readUnsignedByte(); // noc - if (noc > 0) { - buf.skipBytes(19); // lte-srv - for (short i = 1; i < noc; i++) { - buf.skipBytes(5); // lte-nbr - } - } - } - if (type == MSG_WARNING) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); @@ -432,7 +421,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { ByteBuf content = Unpooled.buffer(); if (type == MSG_LOGIN) { content.writeInt((int) (System.currentTimeMillis() / 1000)); - content.writeByte(1); // protocol version + content.writeShort(1); // protocol version content.writeByte(0); // action mask } ByteBuf response = EelinkProtocolEncoder.encodeContent( -- cgit v1.2.3 From d9b8f1e2c0a61438136954671c91445bbae6b76e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:04:26 -0800 Subject: Enable LocationIQ by default --- debug.xml | 3 --- setup/default.xml | 6 ++++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/debug.xml b/debug.xml index 796442364..f9515bb2b 100644 --- a/debug.xml +++ b/debug.xml @@ -10,9 +10,6 @@ true true - false - ban - true org.h2.Driver diff --git a/setup/default.xml b/setup/default.xml index f314413f1..407f3f8bf 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -14,8 +14,10 @@ ./web false - false - google + true + nominatim + https://us1.locationiq.com/v1/reverse.php + pk.b34237342901fc175252c790d1674dcc info ./logs/tracker-server.log -- cgit v1.2.3 From 0fea1a39bea08a43771fc08becdf5d7f2f392531 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:19:13 -0800 Subject: Fix status decoding --- .../java/org/traccar/protocol/MobilogixProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index f3b70e40c..86c89e336 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -47,9 +47,9 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+)") // battery .groupBegin() .text(",") - .number("(d)") // valid + .number("(d)") // satellites .number("(d)") // rssi - .number("(d),") // satellites + .number("(d),") // valid .number("(-?d+.d+),") // latitude .number("(-?d+.d+),") // longitude .number("(d+.?d*),") // speed @@ -127,12 +127,12 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(7)) { + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_RSSI, 6 * parser.nextInt() - 111); + position.setValid(parser.nextInt() > 0); position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setLatitude(parser.nextDouble()); position.setLongitude(parser.nextDouble()); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); -- cgit v1.2.3 From 610bd8d84705b5cfa43f2bcf50d6f0c841ecf260 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:52:29 -0800 Subject: Add custom frame decoder --- .../traccar/protocol/TechtoCruzFrameDecoder.java | 44 ++++++++++++++++++++++ .../org/traccar/protocol/TechtoCruzProtocol.java | 3 +- .../protocol/TechtoCruzFrameDecoderTest.java | 25 ++++++++++++ .../protocol/TechtoCruzProtocolDecoderTest.java | 3 ++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java create mode 100644 src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java diff --git a/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java new file mode 100644 index 000000000..8b9152e8b --- /dev/null +++ b/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java @@ -0,0 +1,44 @@ +/* + * 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 index 890a8abb1..a217ea738 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -15,7 +15,6 @@ */ package org.traccar.protocol; -import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; @@ -28,7 +27,7 @@ public class TechtoCruzProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new TechtoCruzFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechtoCruzProtocolDecoder(TechtoCruzProtocol.this)); diff --git a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java new file mode 100644 index 000000000..dc4afb784 --- /dev/null +++ b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java @@ -0,0 +1,25 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +import static org.junit.Assert.assertEquals; + +public class TechtoCruzFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new TechtoCruzFrameDecoder(); + + assertEquals( + buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"), + decoder.decode(null, null, buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"))); + + assertEquals( + buffer("$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6"), + decoder.decode(null, null, buffer("$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java index 8f4a7915d..4cef682b4 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class TechtoCruzProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); + verifyNull(decoder, text( + "$$A35,RESPO|G33|8612345678910|CRUZ,*E3")); + } } -- cgit v1.2.3 From a1cc21184376a354088376e5e8b5fd55b15df9b9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 23:33:54 -0800 Subject: Decode extension types --- .../traccar/protocol/HuabaoProtocolDecoder.java | 71 ++++++++++++++++++++++ .../protocol/HuabaoProtocolDecoderTest.java | 6 ++ 2 files changed, 77 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 871410c44..af8c5ba09 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -266,6 +266,72 @@ 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 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()); @@ -346,6 +412,11 @@ 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()); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index bf94c5dc5..63ac0ce16 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,12 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyPosition(decoder, binary( + "7E020000830191715904370A2E00000000800000030158991806CA0FEB00040000010D211108194050010400000003CC14383938363034373831303230373033313836303830011A8001AA810213888202007A8301148401AA8502189B8601338702007D028801338901148A0200998B1131323334353637383941424344454647488C04000200A88D0200828E0114A0002E7E")); + + verifyPosition(decoder, binary( + "7e0200007c0191718447540dcd000000008000000b029eabc204ba78510004000000042111182321120104000017f6cc14383933303237323037303339333033383732373130011d800134810204718202008283010e84017b85021ae986012f870201788901038b114a4e31424a314352364b573333363533358c040008dcb68d02018c8e013da000c07e")); + verifyNotNull(decoder, binary( "7e207002940121523001530047210927151009000e002d80ac210927151010000e002d80ab210927151011000e002d80ac210927151012000e002e80ab210927151013000e002d80ab210927151014000e002d80ab210927151015000e002d80ab210927151016000e002d80aa210927151017000e002e80ab210927151018000e002d80ab210927151019000e002e80ac210927151020000e002d80ab210927151021000e002d80ab210927151022000d002d80ac210927151023000e002d80ac210927151024000e002e80ab210927151025000e002e80b0210927151026000e002e80ab210927151027000e002d80ab210927151028000e002e80b0210927151029000e002d80b0210927151030000e002e80ab210927151031000e002d80ab210927151032000e002d80aa210927151033000e002d80ab210927151034000e002d80ab210927151035000e002d80ab210927151036000e002d80ab210927151037000e002d80ab210927151038000e002d80b0210927151039000d002e80aa210927151040000e002d80ab210927151041000e002d80a5210927151042000e002e80ab210927151043000e002d80aa210927151044000e002d80ab210927151045000e002d80ab210927151046000e002d80ac210927151047000e002e80ab210927151048000e002e80a5210927151049000e002d80ab210927151050000e002d80ab210927151051000e002d80ab210927151052000e002d80ab210927151053000e002d80aa210927151054000e002e80b0210927151055000e002e80ab210927151056000e002d80ac210927151057000e002e80ab210927151058000e002d80ab210927151059000e002e80ab210927151100000e002d80ab210927151101000e002e80aa210927151102000e002d80a6210927151103000e002e80a5847e")); -- cgit v1.2.3 From 091bbdebf7e8fc0e4e8623141bb25b6ceb18371a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 26 Nov 2021 19:07:08 -0800 Subject: Add FlexAPI protocol support --- setup/default.xml | 1 + .../java/org/traccar/protocol/FlexApiProtocol.java | 37 ++++++++++ .../traccar/protocol/FlexApiProtocolDecoder.java | 85 ++++++++++++++++++++++ .../protocol/FlexApiProtocolDecoderTest.java | 33 +++++++++ 4 files changed, 156 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/FlexApiProtocol.java create mode 100644 src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 407f3f8bf..54e8d495e 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -302,5 +302,6 @@ 5232 5233 5234 + 5235 diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java new file mode 100644 index 000000000..a1e741eee --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -0,0 +1,37 @@ +/* + * 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(1024)); + 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 new file mode 100644 index 000000000..d2b3c6960 --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -0,0 +1,85 @@ +/* + * 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); + position.setTime(new Date(payload.getInt("time") * 1000L)); + position.setLatitude(payload.getJsonNumber("lat").doubleValue()); + position.setLongitude(payload.getJsonNumber("log").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)); + + position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); + position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); + position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); + position.set(Position.KEY_VIN, payload.getString("obd.vin")); + + } else { + + return null; + + } + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java new file mode 100644 index 000000000..04163294f --- /dev/null +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -0,0 +1,33 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class FlexApiProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new FlexApiProtocolDecoder(null); + + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102021111601/obd/info\",\"payload\":{\"obd.ts\":1637225390,\"obd.speed\":0,\"obd.f_lvl\":null,\"obd.odo\":0,\"obd.e_hours\":0,\"obd.ab_level\":null,\"obd.mil\":0,\"obd.dtcs\":null,\"obd.rpm\":0,\"obd.e_load\":null,\"obd.c_temp\":-40,\"obd.o_temp\":-273,\"obd.a_temp\":null,\"obd.f_press\":null,\"obd.t_pos\":0,\"obd.b_volt\":null,\"obd.up_time\":null,\"obd.m_dist\":null,\"obd.m_time\":null,\"obd.d_dist\":null,\"obd.d_time\":null,\"obd.vin\":\"NLVIN123456789ABC\",\"obd.brake\":0,\"obd.parking\":0,\"obd.s_w_angle\":null,\"obd.f_rate\":0,\"obd.f_econ\":0,\"obd.a_pos\":null,\"obd.t_dist\":0,\"obd.b_press\":null,\"obd.f_r_press\":null,\"obd.i_temp\":null,\"obd.i_press\":null,\"obd.r_torque\":null,\"obd.f_torque\":null,\"obd.max_avl_torque\":null,\"obd.a_torque\":-125,\"obd.d_e_f_vol\":null,\"obd.mf_mon\":null,\"obd.f_s_mon\":null,\"obd.c_c_mon\":null,\"obd.c_mon\":null,\"obd.h_c_mon\":null,\"obd.e_s_mon\":null,\"obd.s_a_s_mon\":null,\"obd.a_s_r_mon\":null,\"obd.e_g_s_mon\":null,\"obd.e_g_s_h_mon\":null,\"obd.e_v_s_mon\":null,\"obd.c_s_a_s_mon\":null,\"obd.b_p_c_s_mon\":null,\"obd.dpf_mon\":null,\"obd.n_c_mon\":null,\"obd.nmhc_mon\":null,\"obd.o_s_mon\":null,\"obd.o_s_h_mon\":null,\"obd.pf_mon\":null}}xx")); + + verifyPosition(decoder, text( + "${\"topic\":\"v1/VF3102021111601/gnss/info\",\"payload\":{\"time\":1637225390,\"lat\":30.587942,\"log\":104.053543,\"gnss.altitude\":480.399994,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":0.900000,\"gnss.fix\":4,\"gnss.num_sv\":11}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/motion/info\",\"payload\":{\"motion.ts\":1637225450,\"motion.ax\":0.009272,\"motion.ay\":0.278404,\"motion.az\":-0.941596,\"motion.gx\":0.420000,\"motion.gy\":-0.490000,\"motion.gz\":0.140000}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/sysinfo/info\",\"payload\":{\"sysinfo.ts\":1637224740,\"sysinfo.model_name\":\"310\",\"sysinfo.oem_name\":\"inhand\",\"sysinfo.serial_number\":\"VF3102021111601\",\"sysinfo.firmware_version\":\"VT3_V1.1.32\",\"sysinfo.product_number\":\"FQ58\",\"sysinfo.description\":\"www.inhand.com.cn\"}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/io/info\",\"payload\":{\"io.ts\":1637227722,\"io.AI1\":0,\"io.DI1\":1,\"io.DI2\":0,\"io.DI3\":0,\"io.DI4\":0,\"io.DI1_pullup\":0,\"io.DI2_pullup\":0,\"io.DI3_pullup\":0,\"io.DI4_pullup\":0,\"io.DO1\":0,\"io.DO2\":0,\"io.DO3\":0,\"io.IGT\":1}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/cellular1/info\",\"payload\":{\"modem1.ts\":1637225330,\"modem1.imei\":\"863674047324999\",\"modem1.imsi\":\"460111150414721\",\"modem1.iccid\":\"89860319482086580401\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":25,\"modem1.reg_status\":1,\"modem1.operator\":\"46011\",\"modem1.network\":3,\"modem1.lac\":\"EA00\",\"modem1.cell_id\":\"E779B81\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":3,\"cellular1.ip\":\"10.136.143.193\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"10.64.64.64\",\"cellular1.dns1\":\"223.5.5.5\",\"cellular1.up_at\":450}}xx")); + + } + +} -- cgit v1.2.3 From 542e70a1d4aca4fa3260b86993a1b3558d81e508 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 28 Nov 2021 21:49:13 -0800 Subject: Support fault codes --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index af8c5ba09..297f26f51 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -322,6 +322,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { 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; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 63ac0ce16..238799fac 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyAttribute(decoder, binary( + "7e0200008e01917159043700b300000000800000030158990606ca0fd7000400000000211129111705010400000000cc14383938363037423831303230393031363239363830010d8001aa81021388820200858301148401aa8502189b8601338702007e8801338901148a0200998b1131323334353637383941424344454647488c04000200a88d0200828e0114a00b50353338662c5530323966037e"), + Position.KEY_DTCS, "P538f U029f"); + verifyPosition(decoder, binary( "7E020000830191715904370A2E00000000800000030158991806CA0FEB00040000010D211108194050010400000003CC14383938363034373831303230373033313836303830011A8001AA810213888202007A8301148401AA8502189B8601338702007D028801338901148A0200998B1131323334353637383941424344454647488C04000200A88D0200828E0114A0002E7E")); -- cgit v1.2.3 From 480aee67810d6cd39e1d8efcdc2bed9b52789292 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 29 Nov 2021 20:49:25 -0800 Subject: Update RSSI decoding --- src/main/java/org/traccar/protocol/BceProtocolDecoder.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index c1a69981d..535827f3c 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -90,11 +90,13 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 14)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShortLE(), buf.readUnsignedByte(), - buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), - buf.readUnsignedByte()))); - buf.readUnsignedByte(); + 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))); } } -- cgit v1.2.3 From 9bb414a077ec263de5bc89948c3c104d46c968e9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 Nov 2021 21:04:41 -0800 Subject: Fix archive decoding --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 297f26f51..aa85ea061 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -581,7 +581,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { int endIndex = buf.readUnsignedShort() + buf.readerIndex(); Position position = decodeLocation(deviceSession, buf); - if (locationType == 0) { + if (locationType > 0) { position.set(Position.KEY_ARCHIVE, true); } positions.add(position); -- cgit v1.2.3 From 97bca437b8e92d69a71e753d969a758064f7ddbd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 Nov 2021 21:23:46 -0800 Subject: Support JT701D acknowledgement --- .../java/org/traccar/protocol/Jt600ProtocolDecoder.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 37c1674d4..dc4bd3486 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -141,6 +141,8 @@ 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()); @@ -160,6 +162,9 @@ 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); @@ -232,7 +237,15 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } - buf.readUnsignedByte(); // index + 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)); + } + } return positions; } -- cgit v1.2.3 From ff97d923cf7f06ed2a985b67b182943b2ff56613 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 1 Dec 2021 23:15:22 -0800 Subject: Update LocationIQ keys --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 54e8d495e..83788b19b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -17,7 +17,7 @@ true nominatim https://us1.locationiq.com/v1/reverse.php - pk.b34237342901fc175252c790d1674dcc + pk.689d849289c8c63708068b2ff1f63b2d info ./logs/tracker-server.log -- cgit v1.2.3 From bff2f2d61878390827ed452bd8a6c4e48f89083b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Dec 2021 20:39:23 -0800 Subject: Fix temperature decoding --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 7f7873e50..d56826cd9 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -232,6 +232,11 @@ 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) { @@ -281,7 +286,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", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Humidity", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "LightSensor", buf.readUnsignedShort()); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); @@ -290,7 +295,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", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Door", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); break; -- cgit v1.2.3 From d7aabe103f4a560353d9ed16d541540b834c5e19 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Dec 2021 08:28:19 -0800 Subject: Additional alarm field --- .../org/traccar/protocol/TopinProtocolDecoder.java | 29 ++++++++++++++-------- .../traccar/protocol/TopinProtocolDecoderTest.java | 4 +++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 267bce562..40a583f2a 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -93,6 +93,19 @@ 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 { @@ -158,17 +171,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { if (buf.readableBytes() >= 5) { position.setAltitude(buf.readShort()); - - 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); - } + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); } ByteBuf content = Unpooled.buffer(); @@ -246,6 +249,10 @@ 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(); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index 331be974c..e8da93006 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class TopinProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780d0103593390754169634d0d0a")); + verifyAttribute(decoder, binary( + "7878006921120412565802010601071e4a9764071e4a9864010d0a"), + Position.KEY_ALARM, Position.ALARM_VIBRATION); + verifyAttribute(decoder, binary( "787801940D0A"), Position.KEY_ALARM, Position.ALARM_VIBRATION); -- cgit v1.2.3 From c0c7077ab4dd21382d880a250f424d093da26d7b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 5 Dec 2021 23:27:38 -0800 Subject: Make property final --- src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index f71620d8a..33cd84a47 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 String url; + private final String url; public UniversalGeolocationProvider(String url, String key) { this.url = url + "?key=" + key; -- cgit v1.2.3 From 955c1abe0753a030846db552c6eea262d7d326d1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Dec 2021 22:05:37 -0800 Subject: Alternative alarm type set --- .../org/traccar/protocol/T800xProtocolDecoder.java | 26 ++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index d56826cd9..b15688df0 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -77,7 +77,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm(int value) { + private String decodeAlarm1(int value) { switch (value) { case 1: return Position.ALARM_POWER_CUT; @@ -107,6 +107,28 @@ 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)) @@ -374,7 +396,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } int alarm = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + position.set(Position.KEY_ALARM, header != 0x2727 ? decodeAlarm1(alarm) : decodeAlarm2(alarm)); if (header != 0x2727) { -- cgit v1.2.3 From b845750ff5be762098b8d246fbb2ca4f35b7e9c5 Mon Sep 17 00:00:00 2001 From: telubato Date: Wed, 8 Dec 2021 15:58:56 +0000 Subject: Add new IO's --- .../org/traccar/protocol/RuptelaProtocolDecoder.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5c2885a8b..2812d22ff 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -102,6 +102,12 @@ 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; @@ -110,22 +116,19 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; - case 198: - if (readValue(buf, length, false) > 0) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - break; - case 199: - case 200: + case 134: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } break; - case 201: + case 136: 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; -- cgit v1.2.3 From 21eab8d6d4ce37c1d6bf20e9dbb897fabf9a0eea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Dec 2021 23:16:28 -0800 Subject: Increase frame limit --- src/main/java/org/traccar/protocol/FlexApiProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index a1e741eee..bc6a49907 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -27,7 +27,7 @@ public class FlexApiProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new LineBasedFrameDecoder(5120)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); } -- cgit v1.2.3 From f020e0472d4544c7f968d8fb2504ad8e85174a49 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Dec 2021 19:23:38 -0800 Subject: Handle missing attributes --- .../org/traccar/protocol/FlexApiProtocolDecoder.java | 16 ++++++++++++---- .../org/traccar/protocol/FlexApiProtocolDecoderTest.java | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index d2b3c6960..25a8f7090 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -68,10 +68,18 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); - position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); - position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); - position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); - position.set(Position.KEY_VIN, payload.getString("obd.vin")); + 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 { diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index 04163294f..83f36f394 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { var decoder = new FlexApiProtocolDecoder(null); + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102029000003/obd/info\",\"payload\":{\"obd.ts\":1639037377,\"obd.speed\":211,\"obd.f_lvl\":50.196079,\"obd.mil\":0,\"obd.dtcs\":0,\"obd.rpm\":14531.250000,\"obd.e_load\":50.980392,\"obd.c_temp\":118,\"obd.o_temp\":56,\"obd.a_temp\":-40,\"obd.f_press\":48,\"obd.t_pos\":51.764706,\"obd.b_volt\":13.782000,\"obd.up_time\":2265,\"obd.m_dist\":4643,\"obd.m_time\":257,\"obd.d_dist\":200,\"obd.d_time\":771,\"obd.vin\":\"LFV3B28R8A3025310\",\"obd.f_rate\":10,\"obd.t_dist\":4843,\"obd.b_press\":101,\"obd.f_r_press\":48,\"obd.i_temp\":37,\"obd.i_press\":32,\"obd.r_torque\":4128,\"obd.a_torque\":2,\"obd.mf_mon\":1,\"obd.f_s_mon\":0,\"obd.c_c_mon\":0,\"obd.c_mon\":1,\"obd.e_s_mon\":1,\"obd.e_v_s_mon\":1,\"obd.o_s_mon\":1,\"obd.o_s_h_mon\":1}}xx")); + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/obd/info\",\"payload\":{\"obd.ts\":1637225390,\"obd.speed\":0,\"obd.f_lvl\":null,\"obd.odo\":0,\"obd.e_hours\":0,\"obd.ab_level\":null,\"obd.mil\":0,\"obd.dtcs\":null,\"obd.rpm\":0,\"obd.e_load\":null,\"obd.c_temp\":-40,\"obd.o_temp\":-273,\"obd.a_temp\":null,\"obd.f_press\":null,\"obd.t_pos\":0,\"obd.b_volt\":null,\"obd.up_time\":null,\"obd.m_dist\":null,\"obd.m_time\":null,\"obd.d_dist\":null,\"obd.d_time\":null,\"obd.vin\":\"NLVIN123456789ABC\",\"obd.brake\":0,\"obd.parking\":0,\"obd.s_w_angle\":null,\"obd.f_rate\":0,\"obd.f_econ\":0,\"obd.a_pos\":null,\"obd.t_dist\":0,\"obd.b_press\":null,\"obd.f_r_press\":null,\"obd.i_temp\":null,\"obd.i_press\":null,\"obd.r_torque\":null,\"obd.f_torque\":null,\"obd.max_avl_torque\":null,\"obd.a_torque\":-125,\"obd.d_e_f_vol\":null,\"obd.mf_mon\":null,\"obd.f_s_mon\":null,\"obd.c_c_mon\":null,\"obd.c_mon\":null,\"obd.h_c_mon\":null,\"obd.e_s_mon\":null,\"obd.s_a_s_mon\":null,\"obd.a_s_r_mon\":null,\"obd.e_g_s_mon\":null,\"obd.e_g_s_h_mon\":null,\"obd.e_v_s_mon\":null,\"obd.c_s_a_s_mon\":null,\"obd.b_p_c_s_mon\":null,\"obd.dpf_mon\":null,\"obd.n_c_mon\":null,\"obd.nmhc_mon\":null,\"obd.o_s_mon\":null,\"obd.o_s_h_mon\":null,\"obd.pf_mon\":null}}xx")); -- cgit v1.2.3 From ffd8ab43e4c2d7fa69753fe73d4e546896d920b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Dec 2021 22:22:28 -0800 Subject: Fix status response --- src/main/java/org/traccar/protocol/TopinProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 40a583f2a..4fe261aa4 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -193,10 +193,12 @@ 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 - int interval = buf.readUnsignedByte(); + buf.readUnsignedByte(); // interval if (buf.readableBytes() >= 1 + 2) { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } @@ -210,8 +212,6 @@ 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; -- cgit v1.2.3 From f910e56a45a4adc08287b6674d011bd25ea52b27 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Dec 2021 10:54:18 -0800 Subject: Token to override current session --- .../org/traccar/api/resource/SessionResource.java | 33 +++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index e3c5d457f..60ce5490a 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 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 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. @@ -57,8 +57,19 @@ 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) { @@ -77,24 +88,20 @@ public class SessionResource extends BaseResource { if (email != null && password != null) { User user = Context.getPermissionsManager().login(email, password); if (user != null) { - 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); + Context.getPermissionsManager().checkUserEnabled(user.getId()); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + return user; } } - } - if (userId != null) { + } else { + 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 -- cgit v1.2.3 From 5a2baafba92958c82b81873dae19c5df7e793eea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Dec 2021 22:19:47 -0800 Subject: Handle missing parameters --- .../traccar/protocol/DmtHttpProtocolDecoder.java | 30 ++++++++++++---------- .../protocol/DmtHttpProtocolDecoderTest.java | 3 +++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 15cf84a5f..815cce987 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -174,21 +174,25 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_INDEX, root.getInt("sqn")); position.set(Position.KEY_EVENT, root.getInt("reason")); - 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("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")); + } } - int input = root.getInt("inputs"); - int output = root.getInt("outputs"); - int status = root.getInt("status"); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - position.set(Position.KEY_STATUS, status); + 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"); diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index bed56ba30..31d0efa12 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { var decoder = new DmtHttpProtocolDecoder(null); + verifyAttributes(decoder, request(HttpMethod.POST, "/", + buffer("{\"date\":\"2021-12-12T16:04:52Z\",\"device\":{\"sn\":\"416581\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278612797427\",\"imei\":\"351358810439486\"},\"sqn\":1549,\"reason\":42,\"counters\":[{\"id\":0,\"val\":5304},{\"id\":3,\"val\":3200},{\"id\":4,\"val\":5066},{\"id\":128,\"val\":1},{\"id\":129,\"val\":8},{\"id\":130,\"val\":0},{\"id\":131,\"val\":0},{\"id\":132,\"val\":0},{\"id\":134,\"val\":1},{\"id\":138,\"val\":0},{\"id\":139,\"val\":36},{\"id\":142,\"val\":1629023},{\"id\":145,\"val\":0},{\"id\":146,\"val\":1}]}"))); + verifyAttributes(decoder, request(HttpMethod.POST, "/", buffer("{\"date\":\"2021-10-04T18:15:47Z\",\"device\":{\"sn\":\"403809\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278483601922\",\"imei\":\"352656106127312\"},\"sqn\":40927,\"reason\":11,\"analogues\":[{\"id\":1,\"val\":4265},{\"id\":3,\"val\":3800},{\"id\":4,\"val\":12},{\"id\":5,\"val\":4251}],\"inputs\":1,\"outputs\":0,\"status\":137}"))); -- cgit v1.2.3 From 54de76fe8645c8da30bbc08d1c8efb1ad472e8b5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Dec 2021 22:51:21 -0800 Subject: Fix time decoding --- src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index 5db7f0bc0..65333ba6e 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -52,7 +52,7 @@ public class HoopoProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - Date time = new Date(OffsetDateTime.parse(eventData.getString("receiveTime")).toInstant().toEpochMilli()); + Date time = new Date(OffsetDateTime.parse(json.getString("eventTime")).toInstant().toEpochMilli()); position.setTime(time); position.setValid(true); -- cgit v1.2.3 From eda05aa8e846b273c4cb30f77ebf3c4db48443ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Dec 2021 22:58:13 -0800 Subject: Decode battery from heartbeat --- .../org/traccar/protocol/MiniFinderProtocolDecoder.java | 17 +++++++++++++++-- .../traccar/protocol/MiniFinderProtocolDecoderTest.java | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index 2b7a960c4..d5be31cec 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 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 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. @@ -143,7 +143,7 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null || !sentence.matches("![3A-D],.*")) { + if (deviceSession == null || !sentence.matches("![35A-D],.*")) { return null; } @@ -161,6 +161,19 @@ 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/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index 2d7e4e597..1a9756226 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class MiniFinderProtocolDecoderTest extends ProtocolTest { @@ -19,7 +20,11 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "!1,123456789012345")); - verifyNull(decoder, text( + verifyAttribute(decoder, text( + "!5,17,V,50"), + Position.KEY_BATTERY_LEVEL, 50); + + verifyAttributes(decoder, text( "!5,17,V")); verifyNull(decoder, text( -- cgit v1.2.3 From 9403fd618339d0ba432794a162f90f22cdc2ebd4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Dec 2021 19:32:38 -0800 Subject: Implement protocol response --- .../org/traccar/protocol/TzoneProtocolDecoder.java | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 249915b39..9e04f0b02 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -19,8 +19,11 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; @@ -30,6 +33,10 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; public class TzoneProtocolDecoder extends BaseProtocolDecoder { @@ -37,6 +44,18 @@ 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())); + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(ack + time, remoteAddress)); + } + } + private String decodeAlarm(Short value) { switch (value) { case 0x01: @@ -348,6 +367,10 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } + if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); + } + return position; } -- cgit v1.2.3 From ddd9a01c6e88e654f3fd377adcee36947e4e1e9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Dec 2021 20:48:39 -0800 Subject: Decode ignition --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 5eab10498..0eb6f8776 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -23,6 +23,7 @@ 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; @@ -190,8 +191,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); } - position.set(Position.KEY_INPUT, parser.nextHexInt()); - position.set(Position.KEY_OUTPUT, parser.nextHexInt()); + int input = parser.nextHexInt(); + int output = parser.nextHexInt(); + + position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); + + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, output); if (parser.hasNext(2)) { -- cgit v1.2.3 From fefa27140fcd7dca13a45f4186797420cb41604c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Dec 2021 22:31:18 -0800 Subject: Alternative location format --- .../org/traccar/protocol/FlexApiProtocolDecoder.java | 18 +++++++++++++++--- .../traccar/protocol/FlexApiProtocolDecoderTest.java | 6 ++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 25a8f7090..167896386 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -55,9 +55,17 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { if (topic.contains("gnss")) { position.setValid(true); - position.setTime(new Date(payload.getInt("time") * 1000L)); - position.setLatitude(payload.getJsonNumber("lat").doubleValue()); - position.setLongitude(payload.getJsonNumber("log").doubleValue()); + + 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()); @@ -81,6 +89,10 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } + } else if (topic.contains("cellular1")) { + + getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); + } else { return null; diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index 83f36f394..a276a01e9 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { var decoder = new FlexApiProtocolDecoder(null); + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102021113001/gnss/info\",\"payload\":{\"gnss.ts\":1639713510,\"gnss.latitude\":30.587509,\"gnss.longitude\":104.053650,\"gnss.altitude\":391,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":1.100000,\"gnss.fix\":4,\"gnss.num_sv\":10}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021113001/cellular1/info\",\"payload\":{\"modem1.ts\":1639713510,\"modem1.imei\":\"863674047326655\",\"modem1.imsi\":\"\",\"modem1.iccid\":\"\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":0,\"modem1.reg_status\":0,\"modem1.operator\":\"\",\"modem1.network\":0,\"modem1.lac\":\"\",\"modem1.cell_id\":\"\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":2,\"cellular1.ip\":\"0.0.0.0\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"0.0.0.0\",\"cellular1.dns1\":\"0.0.0.0\",\"cellular1.up_at\":602}}xx")); + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102029000003/obd/info\",\"payload\":{\"obd.ts\":1639037377,\"obd.speed\":211,\"obd.f_lvl\":50.196079,\"obd.mil\":0,\"obd.dtcs\":0,\"obd.rpm\":14531.250000,\"obd.e_load\":50.980392,\"obd.c_temp\":118,\"obd.o_temp\":56,\"obd.a_temp\":-40,\"obd.f_press\":48,\"obd.t_pos\":51.764706,\"obd.b_volt\":13.782000,\"obd.up_time\":2265,\"obd.m_dist\":4643,\"obd.m_time\":257,\"obd.d_dist\":200,\"obd.d_time\":771,\"obd.vin\":\"LFV3B28R8A3025310\",\"obd.f_rate\":10,\"obd.t_dist\":4843,\"obd.b_press\":101,\"obd.f_r_press\":48,\"obd.i_temp\":37,\"obd.i_press\":32,\"obd.r_torque\":4128,\"obd.a_torque\":2,\"obd.mf_mon\":1,\"obd.f_s_mon\":0,\"obd.c_c_mon\":0,\"obd.c_mon\":1,\"obd.e_s_mon\":1,\"obd.e_v_s_mon\":1,\"obd.o_s_mon\":1,\"obd.o_s_h_mon\":1}}xx")); -- cgit v1.2.3 From 80defa745c10ba5a43fbc0b05f66b5567d782348 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Dec 2021 22:34:35 -0800 Subject: Remove unused code --- src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 167896386..d4d539a9e 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -89,10 +89,6 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } - } else if (topic.contains("cellular1")) { - - getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); - } else { return null; -- cgit v1.2.3 From 25dfb6a1fb66f5565ec338928d000d271f7e62db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Dec 2021 23:26:13 -0800 Subject: Encode response message --- src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 9e04f0b02..819c42471 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -17,6 +17,7 @@ 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; @@ -33,6 +34,7 @@ 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; @@ -51,8 +53,10 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { 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(ack + time, remoteAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } -- cgit v1.2.3 From 19f170b8c147935c8df4044a4fa3b6456baad6c7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Dec 2021 23:00:47 -0800 Subject: Add Digital Systems DSF22 protocol --- setup/default.xml | 1 + .../org/traccar/protocol/Dsf22FrameDecoder.java | 44 +++++++++++ .../java/org/traccar/protocol/Dsf22Protocol.java | 40 ++++++++++ .../org/traccar/protocol/Dsf22ProtocolDecoder.java | 90 ++++++++++++++++++++++ .../traccar/protocol/Dsf22FrameDecoderTest.java | 23 ++++++ .../traccar/protocol/Dsf22ProtocolDecoderTest.java | 23 ++++++ 6 files changed, 221 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/Dsf22Protocol.java create mode 100644 src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java create mode 100644 src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 83788b19b..6c0eef111 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -303,5 +303,6 @@ 5233 5234 5235 + 5236 diff --git a/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java b/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java new file mode 100644 index 000000000..388c97f85 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java @@ -0,0 +1,44 @@ +/* + * 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 new file mode 100644 index 000000000..bffc3e419 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -0,0 +1,40 @@ +/* + * 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 new file mode 100644 index 000000000..d5a9df7bc --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -0,0 +1,90 @@ +/* + * 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 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/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java new file mode 100644 index 000000000..fc18b0560 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Dsf22FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Dsf22FrameDecoder(); + + verifyFrame( + binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"), + decoder.decode(null, null, binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"))); + + verifyFrame( + binary("4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401"), + decoder.decode(null, null, binary("4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java new file mode 100644 index 000000000..96cd78f03 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Ignore; +import org.junit.Test; +import org.traccar.ProtocolTest; + +@Ignore +public class Dsf22ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Dsf22ProtocolDecoder(null); + + verifyPositions(decoder, binary( + "4642000101A8EE5F0ECA5FF421B33F524E32610401")); + + verifyPositions(decoder, binary( + "4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401")); + + } + +} -- cgit v1.2.3 From 29c63d9bf48623ef11e89399e4c7c0e09bf1c446 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 27 Dec 2021 15:38:46 +0400 Subject: revert to the original filtering logic --- src/main/java/org/traccar/handler/FilterHandler.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 6331ff773..e8cafabc8 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -147,12 +147,9 @@ public class FilterHandler extends BaseDataHandler { private boolean filter(Position position) { - if (skipAttributes(position)) { - return false; - } - StringBuilder filterType = new StringBuilder(); + // filter out invalid data if (filterInvalid(position)) { filterType.append("Invalid "); } @@ -168,10 +165,8 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - if (filterStatic(position)) { - filterType.append("Static "); - } + // filter out excessive data long deviceId = position.getDeviceId(); if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; @@ -186,13 +181,13 @@ public class FilterHandler extends BaseDataHandler { } else { preceding = getLastReceivedPosition(deviceId); } - if (skipLimit(position, preceding)) { - return false; - } if (filterDuplicate(position, preceding)) { filterType.append("Duplicate "); } - if (filterDistance(position, preceding)) { + 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)) { -- cgit v1.2.3 From 41453ca2ee76372a031ea206c264c1c7cde58ee6 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 27 Dec 2021 22:16:08 +0400 Subject: filtering logic: fix static --- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index e8cafabc8..049512765 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -168,7 +168,7 @@ public class FilterHandler extends BaseDataHandler { // filter out excessive data long deviceId = position.getDeviceId(); - if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { + if (filterDuplicate || filterStatic || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; if (filterRelative) { try { -- cgit v1.2.3