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 +++++++++++++++------- 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'src/main/java') 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); } -- 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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 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(+) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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 (limited to 'src/main/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 (limited to 'src/main/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 (limited to 'src/main/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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(+) (limited to 'src/main/java') 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 (limited to 'src/main/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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(+) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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 (limited to 'src/main/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(-) (limited to 'src/main/java') 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(-) (limited to 'src/main/java') 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