From 34857cb82abb413100fa4aed668cdca7761e54c4 Mon Sep 17 00:00:00 2001 From: Supriyo Date: Mon, 11 Mar 2024 13:09:38 +0530 Subject: feat: add configuration for event forwarding with mqtt --- src/main/java/org/traccar/MainModule.java | 14 +--- .../org/traccar/forward/EventForwarderMqtt.java | 70 +++--------------- .../org/traccar/forward/PositionForwarderMqtt.java | 55 ++++++++++++++ src/main/java/org/traccar/helper/MqttUtil.java | 83 ++++++++++++++++++++++ 4 files changed, 152 insertions(+), 70 deletions(-) create mode 100644 src/main/java/org/traccar/forward/PositionForwarderMqtt.java create mode 100644 src/main/java/org/traccar/helper/MqttUtil.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 3fec4d1e6..c3c3586be 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,17 +35,7 @@ import org.traccar.config.Keys; import org.traccar.database.LdapProvider; import org.traccar.database.OpenIdProvider; import org.traccar.database.StatisticsManager; -import org.traccar.forward.EventForwarder; -import org.traccar.forward.EventForwarderJson; -import org.traccar.forward.EventForwarderAmqp; -import org.traccar.forward.EventForwarderKafka; -import org.traccar.forward.EventForwarderMqtt; -import org.traccar.forward.PositionForwarder; -import org.traccar.forward.PositionForwarderJson; -import org.traccar.forward.PositionForwarderAmqp; -import org.traccar.forward.PositionForwarderKafka; -import org.traccar.forward.PositionForwarderRedis; -import org.traccar.forward.PositionForwarderUrl; +import org.traccar.forward.*; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; @@ -386,6 +376,8 @@ public class MainModule extends AbstractModule { return new PositionForwarderAmqp(config, objectMapper); case "kafka": return new PositionForwarderKafka(config, objectMapper); + case "mqtt": + return new PositionForwarderMqtt(config, objectMapper); case "redis": return new PositionForwarderRedis(config, objectMapper); case "url": diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index 7f4e29384..90e8500ea 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -15,86 +15,38 @@ */ package org.traccar.forward; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.hivemq.client.mqtt.datatypes.MqttQos; -import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; -import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; -import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.MqttUtil; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.UUID; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; public class EventForwarderMqtt implements EventForwarder { - private final Mqtt5AsyncClient client; + private final Mqtt3AsyncClient client; private final ObjectMapper objectMapper; private final String topic; public EventForwarderMqtt(Config config, ObjectMapper objectMapper) { - URI url; - try { - url = new URI(config.getString(Keys.EVENT_FORWARD_URL)); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - - String userInfo = url.getUserInfo(); - Mqtt5SimpleAuth simpleAuth = null; - if (userInfo != null) { - int delimiter = userInfo.indexOf(':'); - if (delimiter == -1) { - throw new IllegalArgumentException("Wrong credentials. Should be in format \"username:password\""); - } else { - simpleAuth = Mqtt5SimpleAuth.builder() - .username(userInfo.substring(0, delimiter++)) - .password(userInfo.substring(delimiter).getBytes()) - .build(); - } - } - - String host = url.getHost(); - int port = url.getPort(); - client = Mqtt5Client.builder() - .identifier("traccar-" + UUID.randomUUID()) - .serverHost(host) - .serverPort(port) - .simpleAuth(simpleAuth) - .automaticReconnectWithDefaultConfig() - .buildAsync(); - - client.connectWith() - .send() - .whenComplete((message, e) -> { - if (e != null) { - throw new RuntimeException(e); - } - }); - + this.topic = config.getString(Keys.EVENT_FORWARD_TOPIC); + client = MqttUtil.createClient(config.getString(Keys.EVENT_FORWARD_URL)); this.objectMapper = objectMapper; - topic = config.getString(Keys.EVENT_FORWARD_TOPIC); } @Override public void forward(EventData eventData, ResultHandler resultHandler) { - byte[] payload; + String payload; try { - payload = objectMapper.writeValueAsString(eventData).getBytes(); + payload = objectMapper.writeValueAsString(eventData); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); return; } - client.publishWith() - .topic(topic) - .qos(MqttQos.AT_LEAST_ONCE) - .payload(payload) - .send() - .whenComplete((message, e) -> resultHandler.onResult(e == null, e)); + MqttUtil.publish(client, topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } -} +} \ No newline at end of file diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java new file mode 100644 index 000000000..e530c76a1 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -0,0 +1,55 @@ +/* + * Copyright 2022 - 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.forward; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.MqttUtil; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; + +public class PositionForwarderMqtt implements PositionForwarder { + private final Mqtt3AsyncClient client; + + @Override + public void forward(final PositionData positionData, final ResultHandler resultHandler) { + publish(topic, positionData, resultHandler); + } + private final ObjectMapper objectMapper; + + protected final String topic; + + + public PositionForwarderMqtt(final Config config, final ObjectMapper objectMapper) { + this.topic = config.getString(Keys.FORWARD_TOPIC); + this.client = MqttUtil.createClient(config.getString(Keys.FORWARD_URL)); + this.objectMapper = objectMapper; + } + + protected void publish(final String pubTopic, final Object object, final ResultHandler resultHandler) { + final String payload; + try { + payload = objectMapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + return; + } + MqttUtil.publish(client, pubTopic, payload, (message, e) -> resultHandler.onResult(e == null, e)); + } + +} \ No newline at end of file diff --git a/src/main/java/org/traccar/helper/MqttUtil.java b/src/main/java/org/traccar/helper/MqttUtil.java new file mode 100644 index 000000000..54167f65c --- /dev/null +++ b/src/main/java/org/traccar/helper/MqttUtil.java @@ -0,0 +1,83 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; +import java.util.function.BiConsumer; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; +import com.hivemq.client.mqtt.mqtt3.Mqtt3Client; +import com.hivemq.client.mqtt.mqtt3.Mqtt3ClientBuilder; +import com.hivemq.client.mqtt.mqtt3.message.auth.Mqtt3SimpleAuth; +import com.hivemq.client.mqtt.mqtt3.message.publish.Mqtt3Publish; + +public final class MqttUtil { + + private MqttUtil() { + + } + + public static Mqtt3AsyncClient createClient(final String url) { + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + final Mqtt3SimpleAuth simpleAuth = getSimpleAuth(uri); + + final String host = uri.getHost(); + final int port = uri.getPort(); + final Mqtt3ClientBuilder builder = Mqtt3Client.builder().identifier("traccar-" + UUID.randomUUID()) + .serverHost(host).serverPort(port).simpleAuth(simpleAuth).automaticReconnectWithDefaultConfig(); + final Mqtt3AsyncClient client; + + client = builder.buildAsync(); + + + client.connectWith().send().whenComplete((message, e) -> { + throw new RuntimeException(e); + }); + + return client; + } + + private static Mqtt3SimpleAuth getSimpleAuth(final URI uri) { + final String userInfo = uri.getUserInfo(); + Mqtt3SimpleAuth simpleAuth = null; + if (userInfo != null) { + int delimiter = userInfo.indexOf(':'); + if (delimiter == -1) { + throw new IllegalArgumentException("Wrong MQTT credentials. Should be in format \"username:password\""); + } else { + simpleAuth = Mqtt3SimpleAuth.builder().username(userInfo.substring(0, delimiter++)) + .password(userInfo.substring(delimiter).getBytes()).build(); + } + } + return simpleAuth; + } + + public static void publish(final Mqtt3AsyncClient client, final String pubTopic, final String payload, + final BiConsumer whenComplete) { + client.publishWith().topic(pubTopic).qos(MqttQos.AT_LEAST_ONCE).payload(payload.getBytes()).send() + .whenComplete(whenComplete); + } + +} \ No newline at end of file -- cgit v1.2.3 From 87df697b992234caa6e89229dd7fe1ee194859f5 Mon Sep 17 00:00:00 2001 From: Supriyo Date: Tue, 12 Mar 2024 00:08:04 +0530 Subject: linting changes and upgrade mqqt3 to mqtt5 --- src/main/java/org/traccar/MainModule.java | 13 ++++++- .../org/traccar/forward/EventForwarderMqtt.java | 6 ++-- .../org/traccar/forward/PositionForwarderMqtt.java | 6 ++-- src/main/java/org/traccar/helper/MqttUtil.java | 40 ++++++++++------------ 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index c3c3586be..d5b7f7d75 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,7 +35,18 @@ import org.traccar.config.Keys; import org.traccar.database.LdapProvider; import org.traccar.database.OpenIdProvider; import org.traccar.database.StatisticsManager; -import org.traccar.forward.*; +import org.traccar.forward.EventForwarder; +import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.EventForwarderAmqp; +import org.traccar.forward.EventForwarderKafka; +import org.traccar.forward.EventForwarderMqtt; +import org.traccar.forward.PositionForwarder; +import org.traccar.forward.PositionForwarderJson; +import org.traccar.forward.PositionForwarderAmqp; +import org.traccar.forward.PositionForwarderKafka; +import org.traccar.forward.PositionForwarderRedis; +import org.traccar.forward.PositionForwarderUrl; +import org.traccar.forward.PositionForwarderMqtt; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index 90e8500ea..83df795b1 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -21,11 +21,11 @@ import org.traccar.helper.MqttUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; public class EventForwarderMqtt implements EventForwarder { - private final Mqtt3AsyncClient client; + private final Mqtt5AsyncClient client; private final ObjectMapper objectMapper; private final String topic; @@ -49,4 +49,4 @@ public class EventForwarderMqtt implements EventForwarder { MqttUtil.publish(client, topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } -} \ No newline at end of file +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java index e530c76a1..a6d0965b8 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -21,10 +21,10 @@ import org.traccar.helper.MqttUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; public class PositionForwarderMqtt implements PositionForwarder { - private final Mqtt3AsyncClient client; + private final Mqtt5AsyncClient client; @Override public void forward(final PositionData positionData, final ResultHandler resultHandler) { @@ -52,4 +52,4 @@ public class PositionForwarderMqtt implements PositionForwarder { MqttUtil.publish(client, pubTopic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } -} \ No newline at end of file +} diff --git a/src/main/java/org/traccar/helper/MqttUtil.java b/src/main/java/org/traccar/helper/MqttUtil.java index 54167f65c..9fc16012f 100644 --- a/src/main/java/org/traccar/helper/MqttUtil.java +++ b/src/main/java/org/traccar/helper/MqttUtil.java @@ -21,11 +21,11 @@ import java.util.UUID; import java.util.function.BiConsumer; import com.hivemq.client.mqtt.datatypes.MqttQos; -import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; -import com.hivemq.client.mqtt.mqtt3.Mqtt3Client; -import com.hivemq.client.mqtt.mqtt3.Mqtt3ClientBuilder; -import com.hivemq.client.mqtt.mqtt3.message.auth.Mqtt3SimpleAuth; -import com.hivemq.client.mqtt.mqtt3.message.publish.Mqtt3Publish; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientBuilder; +import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PublishResult; public final class MqttUtil { @@ -33,7 +33,7 @@ public final class MqttUtil { } - public static Mqtt3AsyncClient createClient(final String url) { + public static Mqtt5AsyncClient createClient(final String url) { URI uri; try { uri = new URI(url); @@ -41,17 +41,14 @@ public final class MqttUtil { throw new RuntimeException(e); } - final Mqtt3SimpleAuth simpleAuth = getSimpleAuth(uri); + Mqtt5SimpleAuth simpleAuth = getSimpleAuth(uri); - final String host = uri.getHost(); - final int port = uri.getPort(); - final Mqtt3ClientBuilder builder = Mqtt3Client.builder().identifier("traccar-" + UUID.randomUUID()) + String host = uri.getHost(); + int port = uri.getPort(); + Mqtt5ClientBuilder builder = Mqtt5Client.builder().identifier("traccar-" + UUID.randomUUID()) .serverHost(host).serverPort(port).simpleAuth(simpleAuth).automaticReconnectWithDefaultConfig(); - final Mqtt3AsyncClient client; - + Mqtt5AsyncClient client; client = builder.buildAsync(); - - client.connectWith().send().whenComplete((message, e) -> { throw new RuntimeException(e); }); @@ -59,25 +56,26 @@ public final class MqttUtil { return client; } - private static Mqtt3SimpleAuth getSimpleAuth(final URI uri) { - final String userInfo = uri.getUserInfo(); - Mqtt3SimpleAuth simpleAuth = null; + private static Mqtt5SimpleAuth getSimpleAuth(final URI uri) { + String userInfo = uri.getUserInfo(); + Mqtt5SimpleAuth simpleAuth = null; if (userInfo != null) { int delimiter = userInfo.indexOf(':'); if (delimiter == -1) { throw new IllegalArgumentException("Wrong MQTT credentials. Should be in format \"username:password\""); } else { - simpleAuth = Mqtt3SimpleAuth.builder().username(userInfo.substring(0, delimiter++)) + simpleAuth = Mqtt5SimpleAuth.builder().username(userInfo.substring(0, delimiter++)) .password(userInfo.substring(delimiter).getBytes()).build(); } } return simpleAuth; } - public static void publish(final Mqtt3AsyncClient client, final String pubTopic, final String payload, - final BiConsumer whenComplete) { + public static void publish(final Mqtt5AsyncClient client, final String pubTopic, final String payload, + final BiConsumer whenComplete) { client.publishWith().topic(pubTopic).qos(MqttQos.AT_LEAST_ONCE).payload(payload.getBytes()).send() .whenComplete(whenComplete); } -} \ No newline at end of file +} -- cgit v1.2.3 From 75542501573cedb0b7d34a65df5ca650faf82d24 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Mar 2024 17:43:15 -0700 Subject: Remove Mozilla location service --- src/main/java/org/traccar/MainModule.java | 7 ++---- src/main/java/org/traccar/config/Keys.java | 2 +- .../geolocation/MozillaGeolocationProvider.java | 28 ---------------------- .../geolocation/GeolocationProviderTest.java | 2 +- 4 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 3fec4d1e6..acdf48874 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -69,7 +69,6 @@ import org.traccar.geocoder.TestGeocoder; import org.traccar.geocoder.TomTomGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; -import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; @@ -276,18 +275,16 @@ public class MainModule extends AbstractModule { @Provides public static GeolocationProvider provideGeolocationProvider(Config config, Client client) { if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { - String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); + String type = config.getString(Keys.GEOLOCATION_TYPE, "google"); String url = config.getString(Keys.GEOLOCATION_URL); String key = config.getString(Keys.GEOLOCATION_KEY); switch (type) { - case "google": - return new GoogleGeolocationProvider(client, key); case "opencellid": return new OpenCellIdGeolocationProvider(client, url, key); case "unwired": return new UnwiredGeolocationProvider(client, url, key); default: - return new MozillaGeolocationProvider(client, key); + return new GoogleGeolocationProvider(client, key); } } return null; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 02e684875..4aacb2cd8 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1656,7 +1656,7 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is + * Provider to use for LBS location. Available options: google, unwired and opencellid. By default, google is * used. You have to supply a key that you get from corresponding provider. For more information see LBS geolocation * documentation. */ diff --git a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java deleted file mode 100644 index 7eb22dcca..000000000 --- a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.geolocation; - -import jakarta.ws.rs.client.Client; - -public class MozillaGeolocationProvider extends UniversalGeolocationProvider { - - private static final String URL = "https://location.services.mozilla.com/v1/geolocate"; - - public MozillaGeolocationProvider(Client client, String key) { - super(client, URL, key != null ? key : "test"); - } - -} diff --git a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java index da5ae3340..c1fa6dbbe 100644 --- a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java +++ b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java @@ -19,7 +19,7 @@ public class GeolocationProviderTest extends BaseTest { @Disabled @Test public void testMozilla() throws Exception { - MozillaGeolocationProvider provider = new MozillaGeolocationProvider(client, null); + GoogleGeolocationProvider provider = new GoogleGeolocationProvider(client, null); Network network = new Network(CellTower.from(208, 1, 2, 1234567)); -- cgit v1.2.3 From 73dffe380b1faa799f6944d730e71b1b85633f76 Mon Sep 17 00:00:00 2001 From: Sahal Ghafur Date: Fri, 15 Mar 2024 11:16:57 +0000 Subject: Update SPO2 Key for Minifinder2 --- src/main/java/org/traccar/model/Position.java | 1 + src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 39f63217d..ac028917b 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -45,6 +45,7 @@ public class Position extends Message { public static final String KEY_HOURS = "hours"; // milliseconds public static final String KEY_STEPS = "steps"; public static final String KEY_HEART_RATE = "heartRate"; + public static final String KEY_SP02 = "spO2"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_IMAGE = "image"; diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 64373e344..e50655b37 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -295,6 +295,13 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HEART_RATE, heartRate); } break; + case 0x41: + buf.readUnsignedIntLE(); // timestamp + int spO2 = buf.readUnsignedByte(); + if (spO2 > 1) { + position.set(Position.KEY_SP02, spO2); + } + break; default: break; } -- cgit v1.2.3 From a9b08325240b3f4c76d5f6a042c6740b1f81a889 Mon Sep 17 00:00:00 2001 From: Sahal Ghafur Date: Fri, 15 Mar 2024 13:28:23 +0000 Subject: Updated Position Key for spO2 --- src/main/java/org/traccar/model/Position.java | 1 - src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index ac028917b..39f63217d 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -45,7 +45,6 @@ public class Position extends Message { public static final String KEY_HOURS = "hours"; // milliseconds public static final String KEY_STEPS = "steps"; public static final String KEY_HEART_RATE = "heartRate"; - public static final String KEY_SP02 = "spO2"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_IMAGE = "image"; diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index e50655b37..2d6bde89f 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -299,7 +299,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedIntLE(); // timestamp int spO2 = buf.readUnsignedByte(); if (spO2 > 1) { - position.set(Position.KEY_SP02, spO2); + position.set("spO2", spO2); } break; default: -- cgit v1.2.3 From 22b0611d9c00e70f4b70787e314075afcd4538ec Mon Sep 17 00:00:00 2001 From: Supriyo Date: Sat, 16 Mar 2024 12:36:48 +0530 Subject: feat: refractor mqtt utils to MqttClient like EmqxClient --- .../org/traccar/forward/EventForwarderMqtt.java | 10 +-- src/main/java/org/traccar/forward/MqttClient.java | 76 ++++++++++++++++++++ .../org/traccar/forward/PositionForwarderMqtt.java | 9 +-- src/main/java/org/traccar/helper/MqttUtil.java | 81 ---------------------- 4 files changed, 82 insertions(+), 94 deletions(-) create mode 100644 src/main/java/org/traccar/forward/MqttClient.java delete mode 100644 src/main/java/org/traccar/helper/MqttUtil.java diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index 83df795b1..7d1c7dd3c 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -17,22 +17,20 @@ package org.traccar.forward; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.helper.MqttUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; public class EventForwarderMqtt implements EventForwarder { - private final Mqtt5AsyncClient client; + private final MqttClient mqttClient; private final ObjectMapper objectMapper; private final String topic; public EventForwarderMqtt(Config config, ObjectMapper objectMapper) { this.topic = config.getString(Keys.EVENT_FORWARD_TOPIC); - client = MqttUtil.createClient(config.getString(Keys.EVENT_FORWARD_URL)); + mqttClient = new MqttClient(config.getString(Keys.FORWARD_URL)); this.objectMapper = objectMapper; } @@ -41,12 +39,10 @@ public class EventForwarderMqtt implements EventForwarder { String payload; try { payload = objectMapper.writeValueAsString(eventData); + mqttClient.publish(topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); - return; } - - MqttUtil.publish(client, topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } } diff --git a/src/main/java/org/traccar/forward/MqttClient.java b/src/main/java/org/traccar/forward/MqttClient.java new file mode 100644 index 000000000..9059fc876 --- /dev/null +++ b/src/main/java/org/traccar/forward/MqttClient.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.forward; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; +import java.util.function.BiConsumer; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientBuilder; +import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PublishResult; + +public class MqttClient { + private final Mqtt5AsyncClient client; + MqttClient(String url) { + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + Mqtt5SimpleAuth simpleAuth = this.getSimpleAuth(uri); + + String host = uri.getHost(); + int port = uri.getPort(); + Mqtt5ClientBuilder builder = Mqtt5Client.builder().identifier("traccar-" + UUID.randomUUID()) + .serverHost(host).serverPort(port).simpleAuth(simpleAuth).automaticReconnectWithDefaultConfig(); + + client = builder.buildAsync(); + client.connectWith().send().whenComplete((message, e) -> { + throw new RuntimeException(e); + }); + } + + + private Mqtt5SimpleAuth getSimpleAuth(final URI uri) { + String userInfo = uri.getUserInfo(); + Mqtt5SimpleAuth simpleAuth = null; + if (userInfo != null) { + int delimiter = userInfo.indexOf(':'); + if (delimiter == -1) { + throw new IllegalArgumentException("Wrong MQTT credentials. Should be in format \"username:password\""); + } else { + simpleAuth = Mqtt5SimpleAuth.builder().username(userInfo.substring(0, delimiter++)) + .password(userInfo.substring(delimiter).getBytes()).build(); + } + } + return simpleAuth; + } + + public void publish(final String pubTopic, final String payload, + final BiConsumer whenComplete) { + client.publishWith().topic(pubTopic).qos(MqttQos.AT_LEAST_ONCE).payload(payload.getBytes()).send() + .whenComplete(whenComplete); + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java index a6d0965b8..a22c3bee6 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -17,14 +17,12 @@ package org.traccar.forward; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.helper.MqttUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; public class PositionForwarderMqtt implements PositionForwarder { - private final Mqtt5AsyncClient client; + private final MqttClient mqttClient; @Override public void forward(final PositionData positionData, final ResultHandler resultHandler) { @@ -37,7 +35,7 @@ public class PositionForwarderMqtt implements PositionForwarder { public PositionForwarderMqtt(final Config config, final ObjectMapper objectMapper) { this.topic = config.getString(Keys.FORWARD_TOPIC); - this.client = MqttUtil.createClient(config.getString(Keys.FORWARD_URL)); + mqttClient = new MqttClient(config.getString(Keys.FORWARD_URL)); this.objectMapper = objectMapper; } @@ -45,11 +43,10 @@ public class PositionForwarderMqtt implements PositionForwarder { final String payload; try { payload = objectMapper.writeValueAsString(object); + mqttClient.publish(pubTopic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); - return; } - MqttUtil.publish(client, pubTopic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } } diff --git a/src/main/java/org/traccar/helper/MqttUtil.java b/src/main/java/org/traccar/helper/MqttUtil.java deleted file mode 100644 index 9fc16012f..000000000 --- a/src/main/java/org/traccar/helper/MqttUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2023 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.helper; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.UUID; -import java.util.function.BiConsumer; - -import com.hivemq.client.mqtt.datatypes.MqttQos; -import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; -import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; -import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientBuilder; -import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; -import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PublishResult; - -public final class MqttUtil { - - private MqttUtil() { - - } - - public static Mqtt5AsyncClient createClient(final String url) { - URI uri; - try { - uri = new URI(url); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - - Mqtt5SimpleAuth simpleAuth = getSimpleAuth(uri); - - String host = uri.getHost(); - int port = uri.getPort(); - Mqtt5ClientBuilder builder = Mqtt5Client.builder().identifier("traccar-" + UUID.randomUUID()) - .serverHost(host).serverPort(port).simpleAuth(simpleAuth).automaticReconnectWithDefaultConfig(); - Mqtt5AsyncClient client; - client = builder.buildAsync(); - client.connectWith().send().whenComplete((message, e) -> { - throw new RuntimeException(e); - }); - - return client; - } - - private static Mqtt5SimpleAuth getSimpleAuth(final URI uri) { - String userInfo = uri.getUserInfo(); - Mqtt5SimpleAuth simpleAuth = null; - if (userInfo != null) { - int delimiter = userInfo.indexOf(':'); - if (delimiter == -1) { - throw new IllegalArgumentException("Wrong MQTT credentials. Should be in format \"username:password\""); - } else { - simpleAuth = Mqtt5SimpleAuth.builder().username(userInfo.substring(0, delimiter++)) - .password(userInfo.substring(delimiter).getBytes()).build(); - } - } - return simpleAuth; - } - - public static void publish(final Mqtt5AsyncClient client, final String pubTopic, final String payload, - final BiConsumer whenComplete) { - client.publishWith().topic(pubTopic).qos(MqttQos.AT_LEAST_ONCE).payload(payload.getBytes()).send() - .whenComplete(whenComplete); - } - -} -- cgit v1.2.3 From ad1e5c4aba6d97673e7b065b061c8f964aedf447 Mon Sep 17 00:00:00 2001 From: supriyo Date: Sat, 16 Mar 2024 20:03:11 +0530 Subject: update copyright text. --- src/main/java/org/traccar/forward/MqttClient.java | 2 +- src/main/java/org/traccar/forward/PositionForwarderMqtt.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/forward/MqttClient.java b/src/main/java/org/traccar/forward/MqttClient.java index 9059fc876..ad3065b58 100644 --- a/src/main/java/org/traccar/forward/MqttClient.java +++ b/src/main/java/org/traccar/forward/MqttClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java index a22c3bee6..abbdc538a 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 - 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -- cgit v1.2.3 From 40acf3bd81ca74684ebdba57357dc5b112559a69 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Mar 2024 07:43:42 -0700 Subject: Clean up formatting --- .../java/org/traccar/forward/EventForwarderMqtt.java | 3 +-- src/main/java/org/traccar/forward/MqttClient.java | 10 +++++----- .../java/org/traccar/forward/PositionForwarderMqtt.java | 17 ++++++----------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index 7d1c7dd3c..ea075fc6c 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -36,9 +36,8 @@ public class EventForwarderMqtt implements EventForwarder { @Override public void forward(EventData eventData, ResultHandler resultHandler) { - String payload; try { - payload = objectMapper.writeValueAsString(eventData); + String payload = objectMapper.writeValueAsString(eventData); mqttClient.publish(topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); diff --git a/src/main/java/org/traccar/forward/MqttClient.java b/src/main/java/org/traccar/forward/MqttClient.java index ad3065b58..416a167ec 100644 --- a/src/main/java/org/traccar/forward/MqttClient.java +++ b/src/main/java/org/traccar/forward/MqttClient.java @@ -28,7 +28,9 @@ import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PublishResult; public class MqttClient { + private final Mqtt5AsyncClient client; + MqttClient(String url) { URI uri; try { @@ -50,8 +52,7 @@ public class MqttClient { }); } - - private Mqtt5SimpleAuth getSimpleAuth(final URI uri) { + private Mqtt5SimpleAuth getSimpleAuth(URI uri) { String userInfo = uri.getUserInfo(); Mqtt5SimpleAuth simpleAuth = null; if (userInfo != null) { @@ -66,9 +67,8 @@ public class MqttClient { return simpleAuth; } - public void publish(final String pubTopic, final String payload, - final BiConsumer whenComplete) { + public void publish( + String pubTopic, String payload, BiConsumer whenComplete) { client.publishWith().topic(pubTopic).qos(MqttQos.AT_LEAST_ONCE).payload(payload.getBytes()).send() .whenComplete(whenComplete); } diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java index abbdc538a..53f0ced19 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -22,16 +22,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class PositionForwarderMqtt implements PositionForwarder { - private final MqttClient mqttClient; - @Override - public void forward(final PositionData positionData, final ResultHandler resultHandler) { - publish(topic, positionData, resultHandler); - } + private final MqttClient mqttClient; private final ObjectMapper objectMapper; - protected final String topic; - + private final String topic; public PositionForwarderMqtt(final Config config, final ObjectMapper objectMapper) { this.topic = config.getString(Keys.FORWARD_TOPIC); @@ -39,11 +34,11 @@ public class PositionForwarderMqtt implements PositionForwarder { this.objectMapper = objectMapper; } - protected void publish(final String pubTopic, final Object object, final ResultHandler resultHandler) { - final String payload; + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { try { - payload = objectMapper.writeValueAsString(object); - mqttClient.publish(pubTopic, payload, (message, e) -> resultHandler.onResult(e == null, e)); + String payload = objectMapper.writeValueAsString(topic); + mqttClient.publish(topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); } -- cgit v1.2.3 From d66174fc5ee33998b5b3960336a47de3d2f00196 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Mar 2024 07:45:22 -0700 Subject: Fix forwarding URL --- src/main/java/org/traccar/forward/EventForwarderMqtt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java index ea075fc6c..7fee495ac 100644 --- a/src/main/java/org/traccar/forward/EventForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -30,7 +30,7 @@ public class EventForwarderMqtt implements EventForwarder { public EventForwarderMqtt(Config config, ObjectMapper objectMapper) { this.topic = config.getString(Keys.EVENT_FORWARD_TOPIC); - mqttClient = new MqttClient(config.getString(Keys.FORWARD_URL)); + mqttClient = new MqttClient(config.getString(Keys.EVENT_FORWARD_URL)); this.objectMapper = objectMapper; } -- cgit v1.2.3 From 5b8b40faebf6996f1d2f5aef4c733dfe13d73b1b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Mar 2024 19:46:44 -0700 Subject: Add local address to connection key --- .../traccar/handler/StandardLoggingHandler.java | 13 ++---- src/main/java/org/traccar/model/LogRecord.java | 21 ++++++--- .../java/org/traccar/session/ConnectionKey.java | 54 ++++++++++++++++++++++ .../org/traccar/session/ConnectionManager.java | 28 +++++------ .../java/org/traccar/session/DeviceSession.java | 6 +-- 5 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/traccar/session/ConnectionKey.java diff --git a/src/main/java/org/traccar/handler/StandardLoggingHandler.java b/src/main/java/org/traccar/handler/StandardLoggingHandler.java index 5978d632e..513602dd8 100644 --- a/src/main/java/org/traccar/handler/StandardLoggingHandler.java +++ b/src/main/java/org/traccar/handler/StandardLoggingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2024 Anton Tananaev (anton@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,8 +28,6 @@ import org.traccar.helper.NetworkUtil; import org.traccar.model.LogRecord; import org.traccar.session.ConnectionManager; -import java.net.InetSocketAddress; - public class StandardLoggingHandler extends ChannelDuplexHandler { private static final Logger LOGGER = LoggerFactory.getLogger(StandardLoggingHandler.class); @@ -48,7 +46,7 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - LogRecord record = createLogRecord(msg); + LogRecord record = createLogRecord(ctx, msg); log(ctx, false, record); super.channelRead(ctx, msg); if (record != null) { @@ -58,16 +56,15 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - log(ctx, true, createLogRecord(msg)); + log(ctx, true, createLogRecord(ctx, msg)); super.write(ctx, msg, promise); } - private LogRecord createLogRecord(Object msg) { + private LogRecord createLogRecord(ChannelHandlerContext ctx, Object msg) { if (msg instanceof NetworkMessage) { NetworkMessage networkMessage = (NetworkMessage) msg; if (networkMessage.getMessage() instanceof ByteBuf) { - LogRecord record = new LogRecord(); - record.setAddress((InetSocketAddress) networkMessage.getRemoteAddress()); + LogRecord record = new LogRecord(ctx.channel().localAddress(), networkMessage.getRemoteAddress()); record.setProtocol(protocol); record.setData(ByteBufUtil.hexDump((ByteBuf) networkMessage.getMessage())); return record; diff --git a/src/main/java/org/traccar/model/LogRecord.java b/src/main/java/org/traccar/model/LogRecord.java index c19163af3..b04f51b32 100644 --- a/src/main/java/org/traccar/model/LogRecord.java +++ b/src/main/java/org/traccar/model/LogRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Anton Tananaev (anton@traccar.org) + * Copyright 2023 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,24 +16,33 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.session.ConnectionKey; import java.net.InetSocketAddress; +import java.net.SocketAddress; public class LogRecord { - private InetSocketAddress address; + private final InetSocketAddress localAddress; + private final InetSocketAddress remoteAddress; - public void setAddress(InetSocketAddress address) { - this.address = address; + public LogRecord(SocketAddress localAddress, SocketAddress remoteAddress) { + this.localAddress = (InetSocketAddress) localAddress; + this.remoteAddress = (InetSocketAddress) remoteAddress; } @JsonIgnore public InetSocketAddress getAddress() { - return address; + return remoteAddress; + } + + @JsonIgnore + public ConnectionKey getConnectionKey() { + return new ConnectionKey(localAddress, remoteAddress); } public String getHost() { - return address.getHostString(); + return remoteAddress.getHostString(); } private String protocol; diff --git a/src/main/java/org/traccar/session/ConnectionKey.java b/src/main/java/org/traccar/session/ConnectionKey.java new file mode 100644 index 000000000..3b7e2ebf8 --- /dev/null +++ b/src/main/java/org/traccar/session/ConnectionKey.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.session; + +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.util.Objects; + +public class ConnectionKey { + + private final SocketAddress localAddress; + private final SocketAddress remoteAddress; + + public ConnectionKey(Channel channel, SocketAddress remoteAddress) { + this(channel.localAddress(), remoteAddress); + } + + public ConnectionKey(SocketAddress localAddress, SocketAddress remoteAddress) { + this.localAddress = localAddress; + this.remoteAddress = remoteAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConnectionKey that = (ConnectionKey) o; + return Objects.equals(localAddress, that.localAddress) && Objects.equals(remoteAddress, that.remoteAddress); + } + + @Override + public int hashCode() { + return Objects.hash(localAddress, remoteAddress); + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 42dcf5ce9..8431a0327 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -66,8 +66,8 @@ public class ConnectionManager implements BroadcastInterface { private final boolean showUnknownDevices; private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); - private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); - private final Map unknownByEndpoint = new ConcurrentHashMap<>(); + private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map unknownByEndpoint = new ConcurrentHashMap<>(); private final Config config; private final CacheManager cacheManager; @@ -108,8 +108,9 @@ public class ConnectionManager implements BroadcastInterface { Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) throws Exception { + ConnectionKey connectionKey = new ConnectionKey(channel, remoteAddress); Map endpointSessions = sessionsByEndpoint.getOrDefault( - remoteAddress, new ConcurrentHashMap<>()); + connectionKey, new ConcurrentHashMap<>()); uniqueIds = Arrays.stream(uniqueIds).filter(Objects::nonNull).toArray(String[]::new); if (uniqueIds.length > 0) { @@ -133,23 +134,23 @@ public class ConnectionManager implements BroadcastInterface { } if (device != null) { - unknownByEndpoint.remove(remoteAddress); + unknownByEndpoint.remove(connectionKey); device.checkDisabled(); DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); if (oldSession != null) { - Map oldEndpointSessions = sessionsByEndpoint.get(oldSession.getRemoteAddress()); + Map oldEndpointSessions = sessionsByEndpoint.get(oldSession.getConnectionKey()); if (oldEndpointSessions != null && oldEndpointSessions.size() > 1) { oldEndpointSessions.remove(device.getUniqueId()); } else { - sessionsByEndpoint.remove(oldSession.getRemoteAddress()); + sessionsByEndpoint.remove(oldSession.getConnectionKey()); } } DeviceSession deviceSession = new DeviceSession( device.getId(), device.getUniqueId(), device.getModel(), protocol, channel, remoteAddress); endpointSessions.put(device.getUniqueId(), deviceSession); - sessionsByEndpoint.put(remoteAddress, endpointSessions); + sessionsByEndpoint.put(connectionKey, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); if (oldSession == null) { @@ -158,7 +159,7 @@ public class ConnectionManager implements BroadcastInterface { return deviceSession; } else { - unknownByEndpoint.put(remoteAddress, firstUniqueId); + unknownByEndpoint.put(connectionKey, firstUniqueId); LOGGER.warn("Unknown device - " + String.join(" ", uniqueIds) + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); return null; @@ -189,7 +190,8 @@ public class ConnectionManager implements BroadcastInterface { public void deviceDisconnected(Channel channel, boolean supportsOffline) { SocketAddress remoteAddress = channel.remoteAddress(); if (remoteAddress != null) { - Map endpointSessions = sessionsByEndpoint.remove(remoteAddress); + ConnectionKey connectionKey = new ConnectionKey(channel, remoteAddress); + Map endpointSessions = sessionsByEndpoint.remove(connectionKey); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { if (supportsOffline) { @@ -199,7 +201,7 @@ public class ConnectionManager implements BroadcastInterface { cacheManager.removeDevice(deviceSession.getDeviceId()); } } - unknownByEndpoint.remove(remoteAddress); + unknownByEndpoint.remove(connectionKey); } } @@ -212,7 +214,7 @@ public class ConnectionManager implements BroadcastInterface { DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); if (deviceSession != null) { cacheManager.removeDevice(deviceId); - sessionsByEndpoint.computeIfPresent(deviceSession.getRemoteAddress(), (e, sessions) -> { + sessionsByEndpoint.computeIfPresent(deviceSession.getConnectionKey(), (e, sessions) -> { sessions.remove(deviceSession.getUniqueId()); return sessions.isEmpty() ? null : sessions; }); @@ -345,9 +347,9 @@ public class ConnectionManager implements BroadcastInterface { } public synchronized void updateLog(LogRecord record) { - var sessions = sessionsByEndpoint.getOrDefault(record.getAddress(), Map.of()); + var sessions = sessionsByEndpoint.getOrDefault(record.getConnectionKey(), Map.of()); if (sessions.isEmpty()) { - String unknownUniqueId = unknownByEndpoint.get(record.getAddress()); + String unknownUniqueId = unknownByEndpoint.get(record.getConnectionKey()); if (unknownUniqueId != null && showUnknownDevices) { record.setUniqueId(unknownUniqueId); listeners.values().stream() diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index f124ca7f9..31d5e6a13 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ public class DeviceSession { return channel; } - public SocketAddress getRemoteAddress() { - return remoteAddress; + public ConnectionKey getConnectionKey() { + return new ConnectionKey(channel, remoteAddress); } public boolean supportsLiveCommands() { -- cgit v1.2.3 From b6be94fef718926f5575257ab2724f5e538e215f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Mar 2024 20:32:16 -0700 Subject: Support 4G TK905B-G battery level --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 ++- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0a8540543..2186fb91f 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -678,7 +678,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(), buf.readUnsignedInt())); position.setNetwork(network); break; - case 0xE1: + case 0x00A8: + case 0x00E1: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; default: diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 164635109..7fd7cc599 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7E0200005300959000194400080000000000000003015DA64806CCB4A8001100000000230816014137010400005B3F30011F310112EB29000C00B28986049910219020787400060089FFFFFFFF000600C5FFFFFFEF0004002D0F4E000300A84CE07E"), + Position.KEY_BATTERY_LEVEL, 76); + verifyAttribute(decoder, binary( "7e55018c418560090010174701022106242122348476113550490700001c06000000074e0000000000000308100000100102020200000a030000000b0803363839363037650c0600000001000afa7e"), "unlockResult", 0x65); -- cgit v1.2.3 From 13f6415ba0a8ca76d1a2cbb3d0ea199361295f1b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 28 Mar 2024 17:58:38 -0700 Subject: Minor formatting change --- src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java index c072e55d0..938d170e6 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -101,10 +101,11 @@ public class AutoTrackProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedByte(); buf.readUnsignedShortLE(); // length + DeviceSession deviceSession; switch (type) { case MSG_LOGIN_REQUEST: String imei = ByteBufUtil.hexDump(buf.readSlice(8)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } -- cgit v1.2.3