diff options
Diffstat (limited to 'src/main/java/org/traccar/protocol')
524 files changed, 7541 insertions, 2254 deletions
diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index d1d81118c..bab1d2339 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -19,17 +19,21 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AdmProtocol extends BaseProtocol { - public AdmProtocol() { + @Inject + public AdmProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AdmFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new AdmProtocolEncoder(AdmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java index 7e3478704..1f940f7e2 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index 3b9cad7c8..bc975c277 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AisProtocol extends BaseProtocol { - public AisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new AisProtocolDecoder(AisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java index 8970f3d4a..a434e6e33 100644 --- a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index 8da2356b9..b85b44382 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AlematicsProtocol extends BaseProtocol { - public AlematicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AlematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AlematicsFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java index 25ccf6856..981437191 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index 9bd0c9163..b0e974c69 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AnytrekProtocol extends BaseProtocol { - public AnytrekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AnytrekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 2, 0, true)); pipeline.addLast(new AnytrekProtocolDecoder(AnytrekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java index c48f59c90..0f9c2b17a 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index 382aa16af..f1d6e659c 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ApelProtocol extends BaseProtocol { - public ApelProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ApelProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ApelProtocolDecoder(ApelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java index c95a0366a..97ed7de96 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 2b9dbf97c..47bb780cb 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AplicomProtocol extends BaseProtocol { - public AplicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AplicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AplicomFrameDecoder()); pipeline.addLast(new AplicomProtocolDecoder(AplicomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index f11312428..0cd8ca37e 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -21,8 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.Checksum; @@ -303,7 +302,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { decodeEventData(position, buf, event); } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) + if (getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) && buf.isReadable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { decodeCanData(buf, position); } diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 1ca4168e4..25b2bf3b8 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AppelloProtocol extends BaseProtocol { - public AppelloProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AppelloProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java index 47e329234..8e182b9fb 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 5ca1ec091..6080df33d 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AquilaProtocol extends BaseProtocol { - public AquilaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AquilaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java index 3c43ddf2a..50ff10469 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index f7826430f..b33c2817f 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Ardi01Protocol extends BaseProtocol { - public Ardi01Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ardi01Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java index 85e9ecfde..07653623a 100644 --- a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 3b485e4a5..4f443aa3a 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +21,32 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ArknavProtocol extends BaseProtocol { - public ArknavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); } }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); + } + }); + } } diff --git a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java index 4982e02fc..4def9c979 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index a29bc1ad3..39c6e8009 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ArknavX8Protocol extends BaseProtocol { - public ArknavX8Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavX8Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java index b570f5423..22c0344d6 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java new file mode 100644 index 000000000..32fba3b52 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class ArmoliProtocol extends BaseProtocol { + + @Inject + public ArmoliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new ArmoliProtocolDecoder(ArmoliProtocol.this)); + pipeline.addLast(new ArmoliProtocolPoller(ArmoliProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java new file mode 100644 index 000000000..cbed64f76 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -0,0 +1,151 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.session.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.ObdDecoder; +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 ArmoliProtocolDecoder extends BaseProtocolDecoder { + + public ArmoliProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("[M") // start + .number("(d{15})") // imei + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .number("([NS])(dd.d{6})") // latitude + .number("([EW])(ddd.d{6})") // longitude + .number("(d)") // valid + .number("(x)") // satellites + .number("(xx)") // speed + .number("(ddd)") // course + .number("(xxx)") // adc 1 + .number("(xxx)") // adc 2 + .number("(xx)") // status + .number("(xx)") // max speed + .number("(x{6})") // distance + .number("(dd)?") // hdop + .number("x{4}") // idle + .number(":(x+)").optional() // alarms + .number("G(x{6})").optional() // g-sensor + .number("H(x{3})").optional() // power + .number("E(x{3})").optional() // battery + .number("!(x+)").optional() // driver + .expression("@A([>0-9A-F]+)").optional() // obd + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + char type = sentence.charAt(1); + + Position position = new Position(getProtocolName()); + DeviceSession deviceSession; + + if (type != 'M') { + if (type == 'W') { + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + position.set( + Position.KEY_RESULT, + sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 1)); + return position; + } + } else if (channel != null && (type == 'Q' || type == 'L')) { + channel.writeAndFlush(new NetworkMessage("[TX,];;", remoteAddress)); + } + return null; + } + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setValid(parser.nextInt() > 0); + + position.set(Position.KEY_SATELLITES, parser.nextHexInt()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt())); + position.setCourse(parser.nextInt()); + + position.set(Position.PREFIX_ADC + 1, parser.nextHexInt() / 27.0 * 1000); + position.set(Position.PREFIX_ADC + 1, parser.nextHexInt() / 27.0 * 1000); + position.set(Position.KEY_STATUS, parser.nextHexInt()); + position.set("maxSpeed", parser.nextHexInt()); + position.set(Position.KEY_ODOMETER, parser.nextHexInt()); + + if (parser.hasNext()) { + position.set(Position.KEY_HDOP, parser.nextInt() * 0.1); + } + if (parser.hasNext()) { + position.set("alarms", parser.next()); + } + if (parser.hasNext()) { + position.set(Position.KEY_G_SENSOR, parser.next()); + } + if (parser.hasNext()) { + position.set(Position.KEY_POWER, parser.nextHexInt() * 0.01); + } + if (parser.hasNext()) { + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 0.01); + } + if (parser.hasNext()) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + } + if (parser.hasNext()) { + String[] values = parser.next().split(">"); + for (int i = 1; i < values.length; i++) { + String value = values[i]; + position.add(ObdDecoder.decodeData( + Integer.parseInt(value.substring(4, 6), 16), + Long.parseLong(value.substring(6), 16), true)); + } + } + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java new file mode 100644 index 000000000..f7bb9f593 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java @@ -0,0 +1,35 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolPoller; +import org.traccar.Protocol; + +import java.net.SocketAddress; + +public class ArmoliProtocolPoller extends BaseProtocolPoller { + + public ArmoliProtocolPoller(Protocol protocol) { + super(180000); + } + + @Override + protected void sendRequest(Channel channel, SocketAddress remoteAddress) { + channel.writeAndFlush("[TX,];;"); + } + +} diff --git a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java index e957a6911..0f6b7a33f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index aecb42c8c..091d5c06f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ArnaviProtocol extends BaseProtocol { - public ArnaviProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArnaviProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ArnaviFrameDecoder()); pipeline.addLast(new ArnaviProtocolDecoder(ArnaviProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java index 68a70c944..361eeeef2 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class ArnaviProtocolDecoder extends BaseProtocolDecoder { @@ -33,6 +35,12 @@ public class ArnaviProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new ArnaviBinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java index b99869e6e..9d82c9ad5 100644 --- a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index 12b0dfb68..021a81e07 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -19,20 +19,24 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AstraProtocol extends BaseProtocol { - public AstraProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AstraProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java index e6f546b9f..366bf9e8b 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 5894f3eab..25e9be86f 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class At2000Protocol extends BaseProtocol { - public At2000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public At2000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new At2000FrameDecoder()); pipeline.addLast(new At2000ProtocolDecoder(At2000Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java index 43798eb67..b81ba306d 100644 --- a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 429708b26..21eb09696 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -18,24 +18,28 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AtrackProtocol extends BaseProtocol { - public AtrackProtocol() { + @Inject + public AtrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackFrameDecoder()); pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 186b81470..340641729 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -20,8 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -54,7 +53,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static final int MIN_DATA_LENGTH = 40; private boolean longDate; - private final boolean decimalFuel; + private boolean decimalFuel; private boolean custom; private String form; @@ -64,17 +63,20 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { public AtrackProtocolDecoder(Protocol protocol) { super(protocol); + } - longDate = Context.getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); - decimalFuel = Context.getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); + @Override + protected void init() { + longDate = getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); + decimalFuel = getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); - custom = Context.getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + custom = getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); if (form != null) { custom = true; } - String alarmMapString = Context.getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); + String alarmMapString = getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); if (alarmMapString != null) { for (String pair : alarmMapString.split(",")) { if (!pair.isEmpty()) { @@ -98,7 +100,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { this.form = form; } - private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { ByteBuf response = Unpooled.buffer(12); response.writeShort(0xfe02); @@ -524,20 +526,24 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private List<Position> decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - int startIndex = -1; - for (int i = 0; i < 4; i++) { - startIndex = sentence.indexOf(',', startIndex + 1); + int positionIndex = -1; + for (int i = 0; i < 5; i++) { + positionIndex = sentence.indexOf(',', positionIndex + 1); } - int endIndex = sentence.indexOf(',', startIndex + 1); - String imei = sentence.substring(startIndex + 1, endIndex); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + String[] headers = sentence.substring(0, positionIndex).split(","); + long id = Long.parseLong(headers[2]); + int index = Integer.parseInt(headers[3]); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, headers[4]); if (deviceSession == null) { return null; } + sendResponse(channel, remoteAddress, id, index); + List<Position> positions = new LinkedList<>(); - String[] lines = sentence.substring(endIndex + 1).split("\r\n"); + String[] lines = sentence.substring(positionIndex + 1).split("\r\n"); for (String line : lines) { Position position = decodeTextLine(deviceSession, line); @@ -626,7 +632,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(time * 1000)); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(String.valueOf(id), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(String.valueOf(id), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index b8ebdaa75..d37884c8b 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AuroProtocol extends BaseProtocol { - public AuroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AuroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java index d7916147b..4489cf27e 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 32bfc0aae..6a68467e2 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AustinNbProtocol extends BaseProtocol { - public AustinNbProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public AustinNbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new AustinNbProtocolDecoder(AustinNbProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java index dc6f3d280..b07b94e20 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +17,13 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.util.TimeZone; import java.util.regex.Pattern; public class AustinNbProtocolDecoder extends BaseProtocolDecoder { @@ -64,7 +63,7 @@ public class AustinNbProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS, TimeZone.getDefault().getID())); + position.setTime(parser.nextDateTime()); position.setValid(true); position.setLatitude(Double.parseDouble(parser.next().replace(',', '.'))); diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 08b5edc7d..0566b1da6 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AutoFonProtocol extends BaseProtocol { - public AutoFonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoFonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AutoFonFrameDecoder()); pipeline.addLast(new AutoFonProtocolDecoder(AutoFonProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java index aa05ca2d7..dd6a0e33c 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index c6dbb681e..bc80e473a 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AutoGradeProtocol extends BaseProtocol { - public AutoGradeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoGradeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java index 5052450b5..f52ac81c9 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 6aa7558bf..80255d3e9 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AutoTrackProtocol extends BaseProtocol { - public AutoTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); pipeline.addLast(new AutoTrackProtocolDecoder(AutoTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java index da7f6b5a6..c072e55d0 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index dbfab4dea..b35a447ff 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class AvemaProtocol extends BaseProtocol { - public AvemaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AvemaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java index 37836ad5f..0793975df 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index 71fc7cb26..c4a0affdc 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Avl301Protocol extends BaseProtocol { - public Avl301Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Avl301Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); pipeline.addLast(new Avl301ProtocolDecoder(Avl301Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java index f6b7db2d6..8f036fc29 100644 --- a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -125,7 +125,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { } position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedMedium()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); int flags = buf.readUnsignedByte(); diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 7f08870ce..582be0b56 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class B2316Protocol extends BaseProtocol { - public B2316Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public B2316Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new B2316ProtocolDecoder(B2316Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index 854107a20..635806b2d 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -116,8 +116,9 @@ public class B2316ProtocolDecoder extends BaseProtocolDecoder { String[] points = item.getString("wi").split(";"); for (String point : points) { String[] values = point.split(","); + String mac = values[0].replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( - values[0].replaceAll("(..)", "$1:"), Integer.parseInt(values[1]))); + mac.substring(0, mac.length() - 1), Integer.parseInt(values[1]))); } } diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index c5e1dd04c..31fb1bd83 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -18,16 +18,20 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class BceProtocol extends BaseProtocol { - public BceProtocol() { + @Inject + public BceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new BceFrameDecoder()); pipeline.addLast(new BceProtocolEncoder(BceProtocol.this)); pipeline.addLast(new BceProtocolDecoder(BceProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index c1a69981d..2c9459584 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -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))); } } diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index 617a24d7a..3859a9273 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -19,13 +19,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class BlackKiteProtocol extends BaseProtocol { - public BlackKiteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlackKiteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); pipeline.addLast(new BlackKiteProtocolDecoder(BlackKiteProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java index 474ceabdc..64fc439c4 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index d5dc5c421..da195f438 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class BlueProtocol extends BaseProtocol { - public BlueProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlueProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0)); pipeline.addLast(new BlueProtocolDecoder(BlueProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java index f35ac6fbe..db59c564d 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index dfea15938..dc6852d50 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class BoxProtocol extends BaseProtocol { - public BoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java index 853fa8f81..8e92b69fb 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BstplProtocol.java b/src/main/java/org/traccar/protocol/BstplProtocol.java new file mode 100644 index 000000000..dde14a2ca --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class BstplProtocol extends BaseProtocol { + + @Inject + public BstplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new BstplProtocolDecoder(BstplProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java new file mode 100644 index 000000000..15c114642 --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java @@ -0,0 +1,137 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class BstplProtocolDecoder extends BaseProtocolDecoder { + + public BstplProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("BSTPL$") // header + .number("(d),") // type + .expression("([^,]+),") // device id + .expression("([AV]),") // validity + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+.d+),([0NS]),") // latitude + .number("(d+.d+),([0EW]),") // longitude + .number("(d+),") // speed + .number("(d+),") // odometer + .number("(d+),") // course + .number("(d+),") // satellites + .number("([01]),") // box open + .number("(d+),") // rssi + .number("([01]),") // charge + .number("([01]),") // ignition + .number("([01]),") // engine + .number("([01]),") // locked + .number("(d+.d+),") // adc + .number("d+,") // reserved + .number("(d+.d+),") // battery + .expression("([^,]+),") // firmware + .number("([^,]+),") // iccid + .number("(d+.d+)") // power + .compile(); + + private String decodeAlarm(int value) { + switch (value) { + case 4: + return Position.ALARM_LOW_BATTERY; + case 5: + return Position.ALARM_ACCELERATION; + case 6: + return Position.ALARM_BRAKING; + case 7: + return Position.ALARM_OVERSPEED; + case 9: + return Position.ALARM_SOS; + default: + return null; + } + } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + int type = parser.nextInt(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(type)); + + position.setValid(parser.next().equals("A")); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_ODOMETER, parser.nextInt() * 1000L); + + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + boolean boxOpen = parser.nextInt() > 0; + if (type == 8 && boxOpen) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + position.set("boxOpen", boxOpen); + + position.set(Position.KEY_RSSI, parser.nextInt()); + + boolean charge = parser.nextInt() > 0; + if (type == 3) { + position.set(Position.KEY_ALARM, charge ? Position.ALARM_POWER_RESTORED : Position.ALARM_POWER_CUT); + } + position.set(Position.KEY_CHARGE, charge); + + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + position.set("engine", parser.nextInt() > 0); + position.set(Position.KEY_BLOCKED, parser.nextInt() > 0); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_ICCID, parser.next()); + position.set(Position.KEY_POWER, parser.nextDouble()); + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index 804621fd3..5cd8ef4fd 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class C2stekProtocol extends BaseProtocol { - public C2stekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public C2stekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 83e62ff86..aef158fc7 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; @@ -49,10 +49,12 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { .number("(-?d+.d+)#") // altitude .number("(d+)#") // battery .number("d+#") // geo area alarm - .number("(x+)#") // alarm - .number("([01])") // armed + .number("(x+)") // alarm + .groupBegin() + .number("#([01])?") // armed .number("([01])") // door .number("([01])#") // ignition + .groupEnd("?") .any() .text("$AP") .compile(); @@ -111,9 +113,13 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt())); - position.set(Position.KEY_ARMED, parser.nextInt() > 0); - position.set(Position.KEY_DOOR, parser.nextInt() > 0); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + if (parser.hasNext()) { + position.set(Position.KEY_ARMED, parser.nextInt() > 0); + } + if (parser.hasNext(2)) { + position.set(Position.KEY_DOOR, parser.nextInt() > 0); + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + } return position; } diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index 232e72a8c..d67308cf2 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CalAmpProtocol extends BaseProtocol { - public CalAmpProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public CalAmpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java index 59b1fdf21..57f9c69ae 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index e340fba25..0538aad72 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CarTrackProtocol extends BaseProtocol { - public CarTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java index ce3345826..3f5418549 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index f08ab3bd9..832d9bb2d 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -21,17 +21,21 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CarcellProtocol extends BaseProtocol { - public CarcellProtocol() { + @Inject + public CarcellProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java index ec640ba71..54ae068fb 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index 2c754a97f..a4413af28 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CarscopProtocol extends BaseProtocol { - public CarscopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarscopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java index 161666adc..f13a1d0eb 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index 44c52d68f..9323b1503 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -19,26 +19,30 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; +import javax.inject.Inject; + public class CastelProtocol extends BaseProtocol { - public CastelProtocol() { + @Inject + public CastelProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 23401b5ee..4aa65245b 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -160,6 +160,9 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { int value; + if (!PID_LENGTH_MAP.containsKey(pids[i])) { + throw new RuntimeException(String.format("Unknown PID 0x%02x", pids[i])); + } switch (PID_LENGTH_MAP.get(pids[i])) { case 1: value = buf.readUnsignedByte(); @@ -443,7 +446,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); return position; @@ -499,7 +502,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // additional flags position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); positions.add(position); } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index dc694da28..61dde3e80 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -34,7 +33,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); - String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); + String uniqueId = getUniqueId(deviceId); buf.writeByte('@'); buf.writeByte('@'); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index 452bdf8d4..d0ca35ef1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CautelaProtocol extends BaseProtocol { - public CautelaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CautelaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java index bddf19b41..37f733ac1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index d910877cf..3287928c7 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -18,24 +18,28 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CellocatorProtocol extends BaseProtocol { - public CellocatorProtocol() { + @Inject + public CellocatorProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorFrameDecoder()); pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 09bd3572f..3573a95ca 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -120,13 +120,15 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // operator / configuration flags buf.readUnsignedByte(); // reason data - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + short event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); position.set("mode", buf.readUnsignedByte()); - long input = buf.readUnsignedIntLE(); + long input = buf.readUnsignedInt(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 3 * 8 + 5)); position.set(Position.KEY_DOOR, BitUtil.check(input, 3 * 8)); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2 * 8 + 7)); position.set(Position.KEY_CHARGE, BitUtil.check(input, 7)); position.set(Position.KEY_INPUT, input); diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index 9157ca35c..caf0aad42 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CguardProtocol extends BaseProtocol { - public CguardProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CguardProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java index d934921f1..90f8e0caf 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 8ab4ce93a..9656b284b 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -19,19 +19,23 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CityeasyProtocol extends BaseProtocol { - public CityeasyProtocol() { + @Inject + public CityeasyProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_SET_TIMEZONE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new CityeasyProtocolEncoder(CityeasyProtocol.this)); pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java index 9c4c7e11d..1b5eb55d4 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index bc7928fba..06e93d79d 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ContinentalProtocol extends BaseProtocol { - public ContinentalProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ContinentalProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new ContinentalProtocolDecoder(ContinentalProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java index 471afa0d6..280871e1e 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 4a09e0311..7f201a31d 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class CradlepointProtocol extends BaseProtocol { - public CradlepointProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CradlepointProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java index a282131ce..924603291 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index cf2a6c0f5..e9466b7e8 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class DingtekProtocol extends BaseProtocol { - public DingtekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DingtekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DingtekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java index 98fe4b7b3..580741ec9 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index 38f49cc05..f83b8349a 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class DishaProtocol extends BaseProtocol { - public DishaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DishaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java index 3223988ab..1327e7a6c 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 34568128f..0dab26cda 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class DmtHttpProtocol extends BaseProtocol { - public DmtHttpProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtHttpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 15cf84a5f..807850778 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; @@ -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/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index 78a5243c0..de56c9372 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DmtProtocol extends BaseProtocol { - public DmtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new DmtProtocolDecoder(DmtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 96b06557a..320aa1b60 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -184,9 +184,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - if (!BitUtil.check(input, 1)) { + if (!BitUtil.check(status, 1)) { position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - } else if (BitUtil.check(input, 6)) { + } else if (BitUtil.check(status, 6)) { position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index 07c827e18..ed627be78 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DolphinProtocol extends BaseProtocol { - public DolphinProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DolphinProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4096, 20, 4, 4, 0, true)); pipeline.addLast(new DolphinProtocolDecoder(DolphinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java index d509b3ec0..b43635a52 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/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..06c99b0f9 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.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 org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class Dsf22Protocol extends BaseProtocol { + + @Inject + public Dsf22Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Dsf22FrameDecoder()); + pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); + } + }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java new file mode 100644 index 000000000..124bbfefa --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -0,0 +1,89 @@ +/* + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.session.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 = String.valueOf(buf.readUnsignedShortLE()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + if (deviceSession == null) { + return null; + } + + List<Position> positions = new LinkedList<>(); + int count = buf.readUnsignedByte(); + + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setLatitude(buf.readIntLE() / 10000000.0); + position.setLongitude(buf.readIntLE() / 10000000.0); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE() * 0.001); + + int status = buf.readUnsignedByte(); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); + position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 1)); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 4)); + position.set(Position.KEY_ALARM, BitUtil.check(status, 6) ? Position.ALARM_JAMMING : null); + position.set(Position.KEY_STATUS, status); + + positions.add(position); + + } + + if (channel != null) { + byte[] response = {0x01}; + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); + } + + return positions; + } + +} diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index 04c4f2bd1..363a2c5d9 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class DualcamProtocol extends BaseProtocol { - public DualcamProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DualcamProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DualcamFrameDecoder()); pipeline.addLast(new DualcamProtocolDecoder(DualcamProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index c64b8171f..d03f7648d 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -47,7 +46,8 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { private String uniqueId; private int packetCount; private int currentPacket; - private ByteBuf photo; + private boolean video; + private ByteBuf media; @Override protected Object decode( @@ -65,13 +65,26 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { long settings = buf.readUnsignedInt(); if (channel != null && deviceSession != null) { ByteBuf response = Unpooled.buffer(); - if (BitUtil.between(settings, 26, 28) > 0) { + if (BitUtil.between(settings, 26, 30) > 0) { response.writeShort(MSG_FILE_REQUEST); - String file = BitUtil.check(settings, 26) ? "%photof" : "%photor"; + String file; + if (BitUtil.check(settings, 26)) { + video = false; + file = "%photof"; + } else if (BitUtil.check(settings, 27)) { + video = false; + file = "%photor"; + } else if (BitUtil.check(settings, 28)) { + video = true; + file = "%videof"; + } else { + video = true; + file = "%videor"; + } response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); } else { - response.writeShort(MSG_COMPLETE); + response.writeShort(MSG_INIT); } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } @@ -80,7 +93,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // length packetCount = buf.readInt(); currentPacket = 1; - photo = Unpooled.buffer(); + media = Unpooled.buffer(); if (channel != null) { ByteBuf response = Unpooled.buffer(); response.writeShort(MSG_RESUME); @@ -91,17 +104,21 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { break; case MSG_DATA: buf.readUnsignedShort(); // length - photo.writeBytes(buf, buf.readableBytes() - 2); + media.writeBytes(buf, buf.readableBytes() - 2); if (currentPacket == packetCount) { deviceSession = getDeviceSession(channel, remoteAddress); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + if (video) { + position.set(Position.KEY_VIDEO, writeMediaFile(uniqueId, media, "h265")); + } else { + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, media, "jpg")); + } } finally { - photo.release(); - photo = null; + media.release(); + media = null; } if (channel != null) { ByteBuf response = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index 05fd8b6e7..1096c945c 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class DwayProtocol extends BaseProtocol { - public DwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java index 9b02c898e..9cf40b011 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 972b36077..39aa61580 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -21,19 +21,23 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EasyTrackProtocol extends BaseProtocol { - public EasyTrackProtocol() { + @Inject + public EasyTrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#\r\n", "#", "\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java index 4fcc48944..805cf1197 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 8a055d643..35fd4fe65 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -19,28 +19,32 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EelinkProtocol extends BaseProtocol { - public EelinkProtocol() { + @Inject + public EelinkProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, false)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 068b19cbc..941b10fef 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -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; @@ -192,30 +193,67 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } + Network network = new Network(); + + int mcc = 0; + int mnc = 0; if (BitUtil.check(flags, 1)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte()))); + mcc = buf.readUnsignedShort(); + mnc = buf.readUnsignedShort(); + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 2)) { - buf.skipBytes(7); // bsid1 + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 3)) { - buf.skipBytes(7); // bsid2 + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 4)) { - buf.skipBytes(7); // bss0 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } if (BitUtil.check(flags, 5)) { - buf.skipBytes(7); // bss1 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } if (BitUtil.check(flags, 6)) { - buf.skipBytes(7); // bss2 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } + + if (BitUtil.check(flags, 7)) { + buf.readUnsignedByte(); // radio access technology + int count = buf.readUnsignedByte(); + int lac = 0; + if (count > 0) { + mcc = buf.readUnsignedShort(); + mnc = buf.readUnsignedShort(); + lac = buf.readUnsignedShort(); // lac + buf.readUnsignedShort(); // tac + buf.readUnsignedInt(); // cid + buf.readUnsignedShort(); // ta + } + for (int i = 0; i < count; i++) { + int cid = buf.readUnsignedShort(); // physical cid + buf.readUnsignedShort(); // e-arfcn + int rssi = buf.readUnsignedByte(); + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); + } + } + + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); } if (type == MSG_WARNING) { diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index 5d4638f37..f257271d4 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class EgtsProtocol extends BaseProtocol { - public EgtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EgtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EgtsFrameDecoder()); pipeline.addLast(new EgtsProtocolDecoder(EgtsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index e65ddb0ef..01d329580 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -291,7 +291,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { if (serviceType == SERVICE_TELEDATA && position.getValid()) { if (useObjectIdAsDeviceId && objectId != 0L) { - deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(objectId)); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(objectId)); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index e462ab322..ebde56f70 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -19,26 +19,30 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EnforaProtocol extends BaseProtocol { - public EnforaProtocol() { + @Inject + public EnforaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java index bfa7a116b..dd1c8017b 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BufferUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index 7ef94d83f..e326481fa 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class EnnfuProtocol extends BaseProtocol { - public EnnfuProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EnnfuProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java index 792ed1098..2198938e2 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java new file mode 100644 index 000000000..dffa1c991 --- /dev/null +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class EnvotechProtocol extends BaseProtocol { + + @Inject + public EnvotechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new EnvotechProtocolDecoder(EnvotechProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java new file mode 100644 index 000000000..750ff2bda --- /dev/null +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -0,0 +1,116 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.session.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class EnvotechProtocolDecoder extends BaseProtocolDecoder { + + public EnvotechProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("$") + .number("dd") // mode + .expression("...,") // hardware + .number("(x+),") // event + .number("x+,") // group + .number("(x+),") // device id + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("xx") // connection status + .number("(dd)") // rssi + .number("d{5},") // mcc + .number("(ddd)") // power + .number("(ddd),") // battery + .number("(xx)") // inputs + .number("(xx),") // outputs + .number("(xxx)?") // fuel + .number("(xxx)?,") // weight + .number("(x{8}),") // status + .expression("[^']*'") + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(d)") // fix + .number("(d+)(d{5})([NS])") // latitude + .number("(d+)(d{5})([EW])") // longitude + .number("(ddd)") // speed + .number("(ddd)") // course + .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; + } + + Position position = new Position(getProtocolName()); + + int event = parser.nextHexInt(); + switch (event) { + case 0x60: + position.set(Position.KEY_ALARM, Position.ALARM_LOCK); + break; + case 0x61: + position.set(Position.KEY_ALARM, Position.ALARM_UNLOCK); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + position.setDeviceTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_POWER, parser.nextInt() * 0.01); + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.PREFIX_OUT, parser.nextHexInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); + position.set("weight", parser.nextHexInt()); + position.set(Position.KEY_STATUS, parser.nextHexLong()); + + position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setValid(parser.nextInt() > 0); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); + position.setSpeed(parser.nextInt()); + position.setCourse(parser.nextInt()); + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index fc1d342e1..0ed80dc6f 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -21,18 +21,22 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EsealProtocol extends BaseProtocol { - public EsealProtocol() { + @Inject + public EsealProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 0a12f781d..dd15c4276 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -17,8 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -32,11 +31,15 @@ import java.util.regex.Pattern; public class EsealProtocolDecoder extends BaseProtocolDecoder { - private final String config; + private String config; public EsealProtocolDecoder(Protocol protocol) { super(protocol); - config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index fb047c207..cb2f59dc8 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -20,22 +20,26 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class EskyProtocol extends BaseProtocol { - public EskyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EskyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EskyFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java index 14b4376d5..4239022d0 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index 692fd4e99..ffc941b69 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ExtremTracProtocol extends BaseProtocol { - public ExtremTracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ExtremTracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java index 9fde6f0a0..706c70825 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index 4a0a12ed3..fd2beaabb 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -19,17 +19,21 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class FifotrackProtocol extends BaseProtocol { - public FifotrackProtocol() { + @Inject + public FifotrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FifotrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new FifotrackProtocolEncoder(FifotrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 5f9326a61..a9d77b46e 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -35,6 +34,10 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class FifotrackProtocolDecoder extends BaseProtocolDecoder { @@ -79,7 +82,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .text("$$") .number("d+,") // length .number("(d+),") // imei - .number("x+,") // index + .number("(x+),") // index .text("A03,") // type .number("(d+)?,") // alarm .number("(dd)(dd)(dd)") // date (yymmdd) @@ -138,16 +141,20 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("xx") .compile(); - private void requestPhoto(Channel channel, SocketAddress socketAddress, String imei, String file) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String imei, String content) { if (channel != null) { - String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); int length = 1 + imei.length() + 1 + content.length(); String response = String.format("##%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } + private void requestPhoto(Channel channel, SocketAddress remoteAddress, String imei, String file) { + String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); + sendResponse(channel, remoteAddress, imei, content); + } + private String decodeAlarm(Integer alarm) { if (alarm != null) { switch (alarm) { @@ -201,11 +208,14 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { return null; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + String imei = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } + String index = parser.next(); + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -244,6 +254,11 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String response = index + ",A03," + dateFormat.format(new Date()); + sendResponse(channel, remoteAddress, imei, response); + return position; } @@ -381,7 +396,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 05b105f93..374cf77e2 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FlespiProtocol extends BaseProtocol { - public FlespiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlespiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder(4096, 8192, 128 * 1024)); pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 83ca74ce5..6e6f9c700 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -54,11 +54,11 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { List<Position> positions = new LinkedList<>(); for (int i = 0; i < result.size(); i++) { JsonObject message = result.getJsonObject(i); - JsonString ident = message.getJsonString("ident"); - if (ident == null) { + JsonString identifier = message.getJsonString("ident"); + if (identifier == null) { continue; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident.getString()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, identifier.getString()); if (deviceSession == null) { continue; } @@ -228,6 +228,15 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_BONNET); } return true; + case "custom.wln_accel_max": + position.set("maxAcceleration", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_brk_max": + position.set("maxBraking", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_crn_max": + position.set("maxCornering", ((JsonNumber) value).doubleValue()); + return true; default: return false; } 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..088072d2d --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -0,0 +1,43 @@ +/* + * 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; +import org.traccar.config.Config; + +import java.nio.charset.StandardCharsets; + +import javax.inject.Inject; + +public class FlexApiProtocol extends BaseProtocol { + + @Inject + public FlexApiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new LineBasedFrameDecoder(5120)); + pipeline.addLast(new StringDecoder(StandardCharsets.US_ASCII)); + pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java new file mode 100644 index 000000000..2dec44e64 --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -0,0 +1,173 @@ +/* + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.session.DeviceSession; +import org.traccar.Protocol; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.util.Date; + +public class FlexApiProtocolDecoder extends BaseProtocolDecoder { + + public FlexApiProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String message = (String) msg; + JsonObject root = Json.createReader(new StringReader(message.substring(1, message.length() - 2))).readObject(); + + String topic = root.getString("topic"); + String clientId = topic.substring(3, topic.indexOf('/', 3)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, clientId); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + JsonObject payload = root.getJsonObject("payload"); + + if (topic.contains("/gnss/")) { + + position.setValid(true); + + if (payload.containsKey("time")) { + position.setTime(new Date(payload.getInt("time") * 1000L)); + position.setLatitude(payload.getJsonNumber("lat").doubleValue()); + position.setLongitude(payload.getJsonNumber("log").doubleValue()); + } else { + position.setTime(new Date(payload.getInt("gnss.ts") * 1000L)); + position.setLatitude(payload.getJsonNumber("gnss.latitude").doubleValue()); + position.setLongitude(payload.getJsonNumber("gnss.longitude").doubleValue()); + } + + position.setValid(payload.getInt("gnss.fix") > 0); + 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")); + position.set(Position.KEY_HDOP, payload.getJsonNumber("gnss.hdop").doubleValue()); + + } else if (topic.contains("/cellular1/")) { + + getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); + + position.set("imei", payload.getString("modem1.imei")); + position.set("imsi", payload.getString("modem1.imsi")); + position.set(Position.KEY_ICCID, payload.getString("modem1.iccid")); + + String operator = payload.getString("modem1.operator"); + if (!operator.isEmpty()) { + CellTower cellTower = CellTower.from( + Integer.parseInt(operator.substring(0, 3)), + Integer.parseInt(operator.substring(3)), + Integer.parseInt(payload.getString("modem1.lac"), 16), + Integer.parseInt(payload.getString("modem1.cell_id"), 16), + payload.getInt("modem1.rssi")); + switch (payload.getInt("modem1.network")) { + case 1: + cellTower.setRadioType("gsm"); + break; + case 2: + cellTower.setRadioType("wcdma"); + break; + case 3: + cellTower.setRadioType("lte"); + break; + default: + break; + } + position.setNetwork(new Network(cellTower)); + } + + } else if (topic.contains("/obd/")) { + + getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); + + if (payload.containsKey("obd.speed")) { + position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); + } + if (payload.containsKey("obd.odo")) { + position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); + } + if (payload.containsKey("obd.rpm")) { + position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); + } + if (payload.containsKey("obd.vin")) { + position.set(Position.KEY_VIN, payload.getString("obd.vin")); + } + + } else if (topic.contains("/motion/")) { + + getLastLocation(position, new Date(payload.getInt("motion.ts") * 1000L)); + + position.set("ax", payload.getJsonNumber("motion.ax").doubleValue()); + position.set("ay", payload.getJsonNumber("motion.ay").doubleValue()); + position.set("az", payload.getJsonNumber("motion.az").doubleValue()); + position.set("gx", payload.getJsonNumber("motion.gx").doubleValue()); + position.set("gy", payload.getJsonNumber("motion.gy").doubleValue()); + position.set("gz", payload.getJsonNumber("motion.gz").doubleValue()); + + } else if (topic.contains("/io/")) { + + getLastLocation(position, new Date(payload.getInt("io.ts") * 1000L)); + + if (payload.containsKey("io.IGT")) { + position.set(Position.KEY_IGNITION, payload.getInt("io.IGT") > 0); + } + + for (String key : payload.keySet()) { + if (key.startsWith("io.AI")) { + position.set(Position.PREFIX_ADC + key.substring(5), payload.getJsonNumber(key).doubleValue()); + } else if (key.startsWith("io.DI") && !key.endsWith("_pullup")) { + position.set(Position.PREFIX_IN + key.substring(5), payload.getInt(key) > 0); + } else if (key.startsWith("io.DO")) { + position.set(Position.PREFIX_OUT + key.substring(5), payload.getInt(key) > 0); + } + } + + } else if (topic.contains("/sysinfo/")) { + + getLastLocation(position, new Date(payload.getInt("sysinfo.ts") * 1000L)); + + position.set("serial", payload.getString("sysinfo.serial_number")); + position.set(Position.KEY_VERSION_FW, payload.getString("sysinfo.firmware_version")); + + } else { + + return null; + + } + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 9343ebeb8..5397156cb 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FlexCommProtocol extends BaseProtocol { - public FlexCommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlexCommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java index 068c0a05c..0d8bd9373 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 0cd55343a..61e315af9 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FlexibleReportProtocol extends BaseProtocol { - public FlexibleReportProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FlexibleReportProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FlexibleReportProtocolDecoder(FlexibleReportProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java index 759f2cd6f..9fcee1aeb 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index ddd1d58f0..ebac8b4de 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FlextrackProtocol extends BaseProtocol { - public FlextrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlextrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java index 9dce22ede..a0dac1c41 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index 9bac773b5..fa45b3817 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FoxProtocol extends BaseProtocol { - public FoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "</fox>")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java index 449f00022..6dd0b0e95 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index bc6b92d5f..dac117c04 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FreedomProtocol extends BaseProtocol { - public FreedomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FreedomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java index 1d2dd3133..27dda1a6d 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index 999b075a1..dce4994ab 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FreematicsProtocol extends BaseProtocol { - public FreematicsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FreematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new FreematicsProtocolDecoder(FreematicsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java index aded35823..4e5200f37 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 73b53ee12..715dd3c9c 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class FutureWayProtocol extends BaseProtocol { - public FutureWayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FutureWayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FutureWayFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java index c2f3781d9..57027b080 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java new file mode 100644 index 000000000..8c67207ad --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class G1rusFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + ByteBuf result = Unpooled.buffer(); + + while (buf.isReadable()) { + int b = buf.readUnsignedByte(); + if (b == 0x1B) { + int ext = buf.readUnsignedByte(); + if (ext == 0x00) { + result.writeByte(0x1B); + } else { + result.writeByte(0xF8); + } + } else { + result.writeByte(b); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java new file mode 100644 index 000000000..f1823762d --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -0,0 +1,40 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class G1rusProtocol extends BaseProtocol { + + @Inject + public G1rusProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new G1rusFrameDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new G1rusProtocolDecoder(G1rusProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java new file mode 100644 index 000000000..17cfbc1eb --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -0,0 +1,165 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +public class G1rusProtocolDecoder extends BaseProtocolDecoder { + public G1rusProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_HEARTBEAT = 0; + public static final int MSG_REGULAR = 1; + public static final int MSG_SMS_FORWARD = 2; + public static final int MSG_SERIAL = 3; + public static final int MSG_MIXED = 4; + + private String readString(ByteBuf buf) { + int length = buf.readUnsignedByte() & 0xF; + return buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + } + + private Position decodeRegular(DeviceSession deviceSession, ByteBuf buf, int type) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000L)); + + if (BitUtil.check(type, 6)) { + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + } + + int dataMask = buf.readUnsignedShort(); + + if (BitUtil.check(dataMask, 0)) { + buf.readUnsignedByte(); // length + readString(buf); // device name + position.set(Position.KEY_VERSION_FW, readString(buf)); + position.set(Position.KEY_VERSION_HW, readString(buf)); + } + + if (BitUtil.check(dataMask, 1)) { + buf.readUnsignedByte(); // length + int locationMask = buf.readUnsignedShort(); + if (BitUtil.check(locationMask, 0)) { + int validity = buf.readUnsignedByte(); + position.set(Position.KEY_SATELLITES, BitUtil.to(validity, 5)); + position.setValid(BitUtil.between(validity, 5, 7) == 2); + } + if (BitUtil.check(locationMask, 1)) { + position.setLatitude(buf.readInt() / 1000000.0); + position.setLongitude(buf.readInt() / 1000000.0); + } + if (BitUtil.check(locationMask, 2)) { + position.setSpeed(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 3)) { + position.setCourse(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 4)) { + position.setAltitude(buf.readShort()); + } + if (BitUtil.check(locationMask, 5)) { + position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 6)) { + position.set(Position.KEY_VDOP, buf.readUnsignedShort()); + } + } + + if (BitUtil.check(dataMask, 2)) { + buf.skipBytes(buf.readUnsignedByte()); + } + + if (BitUtil.check(dataMask, 3)) { + buf.skipBytes(buf.readUnsignedByte()); + } + + if (BitUtil.check(dataMask, 4)) { + buf.readUnsignedByte(); // length + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_DEVICE_TEMP, buf.readUnsignedShort() * 110 / 4096 - 10); + } + + if (BitUtil.check(dataMask, 5)) { + buf.skipBytes(buf.readUnsignedByte()); + } + + if (BitUtil.check(dataMask, 7)) { + buf.skipBytes(buf.readUnsignedByte()); + } + + return position; + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // version + + int type = buf.readUnsignedByte(); + String imei = String.valueOf(buf.readLong()); + buf.readerIndex(buf.readerIndex() - 1); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { + return null; + } + + if (BitUtil.to(type, 6) == MSG_REGULAR) { + + return decodeRegular(deviceSession, buf, type); + + } else if (BitUtil.to(type, 6) == MSG_MIXED) { + + List<Position> positions = new LinkedList<>(); + while (buf.readableBytes() > 5) { + int length = buf.readUnsignedShort(); + int subtype = buf.readUnsignedByte(); + if (BitUtil.to(subtype, 6) == MSG_REGULAR) { + positions.add(decodeRegular(deviceSession, buf, subtype)); + } else { + buf.skipBytes(length - 1); + } + } + return positions.isEmpty() ? null : positions; + + } + + buf.readUnsignedShort(); // checksum + buf.readUnsignedByte(); // tail + + return null; + + } + +} diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index a1570c9b0..90e95574a 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -18,17 +18,21 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GalileoProtocol extends BaseProtocol { - public GalileoProtocol() { + @Inject + public GalileoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); pipeline.addLast(new GalileoProtocolEncoder(GalileoProtocol.this)); pipeline.addLast(new GalileoProtocolDecoder(GalileoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index f29fb9850..fc8a49cf5 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,15 +20,16 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.BitBuffer; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -36,6 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; public class GalileoProtocolDecoder extends BaseProtocolDecoder { @@ -215,7 +217,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { break; case 0xea: position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); break; default: buf.skipBytes(getTagLength(tag)); @@ -231,7 +232,11 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { int header = buf.readUnsignedByte(); if (header == 0x01) { - return decodePositions(channel, remoteAddress, buf); + if (buf.getUnsignedMedium(buf.readerIndex() + 2) == 0x01001c) { + return decodeIridiumPosition(channel, remoteAddress, buf); + } else { + return decodePositions(channel, remoteAddress, buf); + } } else if (header == 0x07) { return decodePhoto(channel, remoteAddress, buf); } @@ -239,10 +244,58 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodePositions( - Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private void decodeMinimalDataSet(Position position, ByteBuf buf) { + BitBuffer bits = new BitBuffer(buf.readSlice(10)); + bits.readUnsigned(1); + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.set(Calendar.DAY_OF_YEAR, 1); + calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); + calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); + calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); + calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); + calendar.add(Calendar.SECOND, bits.readUnsigned(25)); + position.setTime(calendar.getTime()); + + position.setValid(bits.readUnsigned(1) == 0); + position.setLongitude(360 * bits.readUnsigned(22) / 4194304.0 - 180); + position.setLatitude(360 * bits.readUnsigned(21) / 2097152.0 - 90); + if (bits.readUnsigned(1) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + } + + private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + buf.readUnsignedShortLE(); // length + + buf.skipBytes(3); // identification header + buf.readUnsignedIntLE(); // index + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // session status + buf.skipBytes(4); // reserved + buf.readUnsignedIntLE(); // date and time + + buf.skipBytes(23); // coordinates block + + buf.skipBytes(3); // data tag header + decodeMinimalDataSet(position, buf); + + return position; + } + + private List<Position> decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; + int endIndex = (buf.readUnsignedShortLE() & 0x7fff) + buf.readerIndex(); List<Position> positions = new LinkedList<>(); Set<Integer> tags = new HashSet<>(); @@ -251,7 +304,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = new Position(getProtocolName()); - while (buf.readerIndex() < length) { + while (buf.readerIndex() < endIndex) { int tag = buf.readUnsignedByte(); if (tags.contains(tag)) { @@ -287,7 +340,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { if (hasLocation && position.getFixTime() != null) { positions.add(position); - } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) { + } else if (position.hasAttribute(Position.KEY_RESULT)) { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); positions.add(position); @@ -322,14 +375,13 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index ca81caefb..7341b69a3 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -19,20 +19,24 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GatorProtocol extends BaseProtocol { - public GatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java index 087861635..644caee81 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index c87ba946a..97d8633a0 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GenxProtocol extends BaseProtocol { - public GenxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GenxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GenxProtocolDecoder(GenxProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index 2ae9de7a0..6448b6a5a 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -17,8 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -32,7 +31,11 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { public GenxProtocolDecoder(Protocol protocol) { super(protocol); - setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); + } + + @Override + protected void init() { + setReportColumns(getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); } public void setReportColumns(String format) { diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index 063e606db..e1748c9a0 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -21,22 +21,26 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Gl100Protocol extends BaseProtocol { - public Gl100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gl100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java index ae0383e5c..789d87dad 100644 --- a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index c3339bea5..ecd1f5bfa 100644 --- a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index e2d0c6d2a..c7b6a8e7c 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -15,34 +15,37 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; +import javax.inject.Inject; public class Gl200Protocol extends BaseProtocol { - public Gl200Protocol() { + @Inject + public Gl200Protocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gl200FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java index ca1df7a13..a9736c9e7 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import org.traccar.BaseProtocolDecoder; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class Gl200ProtocolDecoder extends BaseProtocolDecoder { @@ -34,6 +36,12 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 683ba476e..517499f02 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -46,11 +45,15 @@ import java.util.regex.Pattern; public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { - private final boolean ignoreFixTime; + private boolean ignoreFixTime; public Gl200TextProtocolDecoder(Protocol protocol) { super(protocol); - ignoreFixTime = Context.getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + ignoreFixTime = getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); } private static final Pattern PATTERN_ACK = new PatternBuilder() @@ -139,7 +142,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(x+)?,") // lac .number("(x+)?,") // cid .groupEnd() - .number("(?:d+|(d+.d))?,") // odometer + .number("(?:d+|(d+.d))?,") // rssi / odometer .compile(); private static final Pattern PATTERN_OBD = new PatternBuilder() @@ -184,7 +187,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:([0-9A-Z]{17}),)?") // vin .expression("[^,]*,") // device name .number("(d+)?,") // power - .number("d{1,2},").optional() // report type + .number("(d{1,2}),").optional() // report type .number("d{1,2},").optional() // count .number("d*,").optional() // reserved .number("(d+),").optional() // battery @@ -208,11 +211,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption .number("(d+)?,") // fuel level .or() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() .number("(-?d),") // rssi .number("(d{1,3}),") // battery + .or() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery .groupEnd() .any() .number("(dddd)(dd)(dd)") // date (yyyymmdd) @@ -349,6 +352,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_DAR = new PatternBuilder() + .text("+RESP:GTDAR,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d),") // warning type + .number("(d{1,2}),,,") // fatigue degree + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -357,15 +376,16 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("d*,") .number("(x{1,2}),") // report type .number("d{1,2},") // count + .number("d*,").optional() // reserved .expression(PATTERN_LOCATION.pattern()) .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer + .number("(?:(d{1,7}.d)|0)?,").optional() // odometer .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer .groupEnd() .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(dd)(dd)(dd)") // time (hhmmss) .text(",") .number("(xxxx)") // count number .text("$").optional() @@ -377,6 +397,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version .number("(d{15}|x{14}),") // imei .any() + .text(",") .number("(d{1,2})?,") // hdop .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course @@ -835,6 +856,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { String vin = parser.next(); Integer power = parser.nextInt(); + Integer reportType = parser.nextInt(); Integer battery = parser.nextInt(); Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); @@ -877,12 +899,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + if (parser.hasNext(2)) { + if (reportType != null) { + position.set(Position.KEY_MOTION, BitUtil.check(reportType, 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(reportType, 1)); + } + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + } if (parser.hasNext()) { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); } position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); decodeDeviceTime(position, parser); if (ignoreFixTime) { @@ -1114,6 +1142,29 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeDar(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_DAR, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int warningType = parser.nextInt(); + int fatigueDegree = parser.nextInt(); + if (warningType == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + position.set("fatigueDegree", fatigueDegree); + } else { + position.set("warningType", warningType); + } + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1305,6 +1356,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "PFA": result = decodePna(channel, remoteAddress, sentence); break; + case "DAR": + result = decodeDar(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; @@ -1325,7 +1379,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } - if (channel != null && Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + if (channel != null && getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { String checksum; if (sentence.endsWith("$")) { checksum = sentence.substring(sentence.length() - 1 - 4, sentence.length() - 1); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index e86b5dc30..16b99f426 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -21,18 +21,22 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GlobalSatProtocol extends BaseProtocol { - public GlobalSatProtocol() { + @Inject + public GlobalSatProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_DISMISS, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "!\r\n", "!")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java index b48df4047..720b61695 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -17,8 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -40,9 +39,12 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder { public GlobalSatProtocolDecoder(Protocol protocol) { super(protocol); + } - format0 = Context.getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); - format1 = Context.getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); + @Override + protected void init() { + format0 = getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); + format1 = getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); } public void setFormat0(String format) { diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index 84cd5565b..293f5fda5 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GlobalstarProtocol extends BaseProtocol { - public GlobalstarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GlobalstarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java index b742d0cac..0ddb95c14 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java @@ -27,7 +27,7 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -151,15 +151,11 @@ public class GlobalstarProtocolDecoder extends BaseHttpProtocolDecoder { position.setCourse(BitUtil.from(flags, 5) * 45); - position.setLatitude(buf.readUnsignedMedium() * 90.0 / (1 << 23)); - if (position.getLatitude() > 90) { - position.setLatitude(position.getLatitude() - 180); - } + double latitude = buf.readUnsignedMedium() * 90.0 / (1 << 23); + position.setLatitude(latitude > 90 ? latitude - 180 : latitude); - position.setLongitude(buf.readUnsignedMedium() * 180.0 / (1 << 23)); - if (position.getLongitude() > 180) { - position.setLongitude(position.getLongitude() - 360); - } + double longitude = buf.readUnsignedMedium() * 180.0 / (1 << 23); + position.setLongitude(longitude > 180 ? longitude - 360 : longitude); int speed = buf.readUnsignedByte(); position.setSpeed(UnitsConverter.knotsFromKph(speed)); diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index 3576bf805..32d642688 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GnxProtocol extends BaseProtocol { - public GnxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GnxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java index c9c221a69..9c8b6879a 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index aaaffac97..607931500 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -21,22 +21,26 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GoSafeProtocol extends BaseProtocol { - public GoSafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GoSafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index a86249224..77649a041 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index 07fe02248..53fcea0d0 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GotopProtocol extends BaseProtocol { - public GotopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GotopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index a867451aa..5c8d0bac2 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -35,7 +35,7 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("(d+),") // imei - .expression("[^,]+,") // type + .expression("([^,]+),") // type .expression("([AV]),") // validity .number("DATE:(dd)(dd)(dd),") // date (yyddmm) .number("TIME:(dd)(dd)(dd),") // time (hhmmss) @@ -56,14 +56,25 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + String type = parser.next(); + if (type.equals("CMD-KEY")) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } else if (type.startsWith("ALM-B")) { + if (Character.getNumericValue(type.charAt(5)) % 2 > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); + } + } + position.setValid(parser.next().equals("A")); position.setTime(parser.nextDateTime()); diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index b6ab10a19..dbffbfdbb 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Gps056Protocol extends BaseProtocol { - public Gps056Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gps056Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gps056FrameDecoder()); pipeline.addLast(new Gps056ProtocolDecoder(Gps056Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java index 0ba79bb51..eea64364e 100644 --- a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index 5356387ce..2725494c5 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -21,11 +21,15 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gps103Protocol extends BaseProtocol { - public Gps103Protocol() { + @Inject + public Gps103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -36,9 +40,9 @@ public class Gps103Protocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -46,9 +50,9 @@ public class Gps103Protocol extends BaseProtocol { pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d74f19179..28efa3c30 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -57,9 +56,12 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .expression("([^,]+)?,") // rfid .groupBegin() - .text("L,,,") + .text("L,") + .groupBegin() + .text(",,") .number("(x+),,") // lac .number("(x+),,,") // cid + .groupEnd("?") .or() .text("F,") .groupBegin() @@ -203,7 +205,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(alarm.substring(2))); } else if (alarm.startsWith("oil ")) { position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(alarm.substring(4))); - } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { + } else if (!position.hasAttribute(Position.KEY_ALARM) && !alarm.equals("tracker")) { position.set(Position.KEY_EVENT, alarm); } @@ -219,12 +221,11 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(2)) { + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); + } - getLastLocation(position, null); - - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); - - } else { + if (parser.hasNext(20)) { String utcHours = parser.next(); String utcMinutes = parser.next(); @@ -262,6 +263,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set("fuel2", parser.nextDouble()); position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + } else { + + getLastLocation(position, null); + } return position; @@ -361,7 +366,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); } finally { photoPackets = 0; photo.release(); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java index e662e9b04..9a899eeeb 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java @@ -49,7 +49,7 @@ public class Gps103ProtocolEncoder extends StringProtocolEncoder implements Stri case Command.TYPE_CUSTOM: return formatCommand(command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_POSITION_STOP: - return formatCommand(command, "**,imei:%s,A", Command.KEY_UNIQUE_ID); + return formatCommand(command, "**,imei:%s,D", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "**,imei:%s,B", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_PERIODIC: diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index a131b6f48..a6a73ae6b 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GpsGateProtocol extends BaseProtocol { - public GpsGateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsGateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java index c158d3212..82da58f1e 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index ad23ece48..12b53342c 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GpsMarkerProtocol extends BaseProtocol { - public GpsMarkerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsMarkerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java index bbb2c31e2..0fef4b7da 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index ce6cc5929..a474b1e53 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class GpsmtaProtocol extends BaseProtocol { - public GpsmtaProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public GpsmtaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java index 31f9401b4..a9b85d255 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 244c3977b..bb66501e2 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -19,11 +19,15 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GranitProtocol extends BaseProtocol { - public GranitProtocol() { + @Inject + public GranitProtocol(Config config) { setSupportedDataCommands( Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE, @@ -32,9 +36,9 @@ public class GranitProtocol extends BaseProtocol { setSupportedTextCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GranitFrameDecoder()); pipeline.addLast(new GranitProtocolEncoder(GranitProtocol.this)); pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java index 292e43a0e..dfc3c10f6 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index a701815d0..425ca9330 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Gs100Protocol extends BaseProtocol { - public Gs100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gs100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gs100ProtocolDecoder(Gs100Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java index 2496aad48..352070107 100644 --- a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index f412ee720..fa05761f6 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Gt02Protocol extends BaseProtocol { - public Gt02Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt02Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); pipeline.addLast(new Gt02ProtocolDecoder(Gt02Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java index 78a3fd3ee..4ecb0b43b 100644 --- a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 9ec8de098..38278121c 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -18,18 +18,22 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gt06Protocol extends BaseProtocol { - public Gt06Protocol() { + @Inject + public Gt06Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gt06FrameDecoder()); pipeline.addLast(new Gt06ProtocolEncoder(Gt06Protocol.this)); pipeline.addLast(new Gt06ProtocolDecoder(Gt06Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0dcdab892..ef09677bf 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -32,7 +31,6 @@ import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; -import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; @@ -70,19 +68,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_3 = 0x27; public static final int MSG_LBS_MULTIPLE_1 = 0x28; public static final int MSG_LBS_MULTIPLE_2 = 0x2E; + public static final int MSG_LBS_MULTIPLE_3 = 0x24; public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; - public static final int MSG_HEARTBEAT = 0x23; - public static final int MSG_ADDRESS_REQUEST = 0x2A; - public static final int MSG_ADDRESS_RESPONSE = 0x97; - public static final int MSG_GPS_LBS_5 = 0x31; - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; - public static final int MSG_WIFI_5 = 0x33; - public static final int MSG_AZ735_GPS = 0x32; // only extended - public static final int MSG_AZ735_ALARM = 0x33; // only extended + public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 + public static final int MSG_HEARTBEAT = 0x23; // GK310 + public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 + public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 + public static final int MSG_WIFI_5 = 0x33; // AZ735 + public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -92,25 +91,63 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; - public static final int MSG_TIME_REQUEST = 0x8A; + public static final int MSG_TIME_REQUEST = 0x8A; // GK310 public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 0x9B; public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; - public static final int MSG_LBS_2 = 0xA1; - public static final int MSG_WIFI_3 = 0xA2; - public static final int MSG_FENCE_SINGLE = 0xA3; - public static final int MSG_FENCE_MULTI = 0xA4; - public static final int MSG_LBS_ALARM = 0xA5; - public static final int MSG_LBS_ADDRESS = 0xA7; - public static final int MSG_OBD = 0x8C; - public static final int MSG_DTC = 0x65; - public static final int MSG_PID = 0x66; - public static final int MSG_BMS = 0x20; - public static final int MSG_MULTIMEDIA = 0x21; - public static final int MSG_BMS_2 = 0x40; - public static final int MSG_MULTIMEDIA_2 = 0x41; - public static final int MSG_ALARM = 0x95; + public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_LBS_2 = 0xA1; // GK310 + public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 & JM-LL301 + public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 + public static final int MSG_OBD = 0x8C; // FM08ABC + public static final int MSG_DTC = 0x65; // FM08ABC + public static final int MSG_PID = 0x66; // FM08ABC + public static final int MSG_BMS = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA = 0x41; // WD-209 + public static final int MSG_ALARM = 0x95; // JC100 + + private enum Variant { + VXT01, + WANWAY_S20, + SR411_MINI, + GT06E_CARD, + BENWAY, + S5, + SPACE10X, + STANDARD, + OBD6, + } + + private Variant variant; + + private static final Pattern PATTERN_FUEL = new PatternBuilder() + .text("!AIOIL,") + .number("d+,") // device address + .number("d+.d+,") // output value + .number("(d+.d+),") // temperature + .expression("[^,]+,") // version + .number("dd") // back wave + .number("d") // software status code + .number("d,") // hardware status code + .number("(d+.d+),") // measured value + .expression("[01],") // movement status + .number("d+,") // excited wave times + .number("xx") // checksum + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .text("Current position!") + .number("Lat:([NS])(d+.d+),") // latitude + .number("Lon:([EW])(d+.d+),") // longitude + .text("Course:").number("(d+.d+),") // course + .text("Speed:").number("(d+.d+),") // speed + .text("DateTime:") + .number("(dddd)-(dd)-(dd) +") // date + .number("(dd):(dd):(dd)") // time + .compile(); private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); @@ -172,6 +209,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_LBS_ALARM: return true; default: return false; @@ -297,9 +335,26 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - int lac = buf.readUnsignedShort(); - long cid = type == MSG_GPS_LBS_6 ? buf.readUnsignedInt() : buf.readUnsignedMedium(); + int mnc; + if (BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6) { + mnc = buf.readUnsignedShort(); + } else { + mnc = buf.readUnsignedByte(); + } + int lac; + if (type == MSG_LBS_ALARM) { + lac = buf.readInt(); + } else { + lac = buf.readUnsignedShort(); + } + long cid; + if (type == MSG_LBS_ALARM) { + cid = buf.readLong(); + } else if (type == MSG_GPS_LBS_6) { + cid = buf.readUnsignedInt(); + } else { + cid = buf.readUnsignedMedium(); + } position.setNetwork(new Network(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid))); @@ -310,7 +365,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { + private void decodeStatus(Position position, ByteBuf buf) { int status = buf.readUnsignedByte(); @@ -332,22 +387,19 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case 4: position.set(Position.KEY_ALARM, Position.ALARM_SOS); break; + case 6: + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + break; case 7: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + if (variant == Variant.VXT01) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + } break; default: break; } - - if (batteryLevel) { - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); - } else { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - } - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - - return true; } private String decodeAlarm(short value) { @@ -367,13 +419,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_OVERSPEED; case 0x0E: case 0x0F: + case 0x19: return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_POWER_OFF; + case 0x0C: case 0x13: + case 0x25: return Position.ALARM_TAMPERING; case 0x14: return Position.ALARM_DOOR; + case 0x18: + return Position.ALARM_REMOVING; + case 0x23: + return Position.ALARM_FALL_DOWN; case 0x29: return Position.ALARM_ACCELERATION; case 0x30: @@ -383,81 +442,27 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_CORNERING; case 0x2C: return Position.ALARM_ACCIDENT; - case 0x23: - return Position.ALARM_FALL_DOWN; default: return null; } } - private static final Pattern PATTERN_FUEL = new PatternBuilder() - .text("!AIOIL,") - .number("d+,") // device address - .number("d+.d+,") // output value - .number("(d+.d+),") // temperature - .expression("[^,]+,") // version - .number("dd") // back wave - .number("d") // software status code - .number("d,") // hardware status code - .number("(d+.d+),") // measured value - .expression("[01],") // movement status - .number("d+,") // excited wave times - .number("xx") // checksum - .compile(); - - private Position decodeFuelData(Position position, String sentence) { - Parser parser = new Parser(PATTERN_FUEL, sentence); - if (!parser.matches()) { - return null; - } - - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); - - return position; - } - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .text("Current position!") - .number("Lat:([NS])(d+.d+),") // latitude - .number("Lon:([EW])(d+.d+),") // longitude - .text("Course:").number("(d+.d+),") // course - .text("Speed:").number("(d+.d+),") // speed - .text("DateTime:") - .number("(dddd)-(dd)-(dd) +") // date - .number("(dd):(dd):(dd)") // time - .compile(); - - private Position decodeLocationString(Position position, String sentence) { - Parser parser = new Parser(PATTERN_LOCATION, sentence); - if (!parser.matches()) { - return null; - } - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setCourse(parser.nextDouble()); - position.setSpeed(parser.nextDouble()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); - - return position; - } - - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedByte(); int dataLength = length - 5; int type = buf.readUnsignedByte(); + Position position = new Position(getProtocolName()); DeviceSession deviceSession = null; if (type != MSG_LOGIN) { deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + position.setDeviceId(deviceSession.getDeviceId()); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } } @@ -467,8 +472,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // type deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (deviceSession != null && !deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } if (dataLength > 10) { @@ -480,23 +485,21 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { offset = -offset; } if (deviceSession != null) { - TimeZone timeZone = deviceSession.getTimeZone(); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); if (timeZone.getRawOffset() == 0) { timeZone.setRawOffset(offset * 1000); - deviceSession.setTimeZone(timeZone); + deviceSession.set(DeviceSession.KEY_TIMEZONE, timeZone); } } - } if (deviceSession != null) { sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); } - } else if (type == MSG_HEARTBEAT) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_HEARTBEAT) { getLastLocation(position, null); @@ -525,6 +528,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); sendResponse(channel, true, MSG_ADDRESS_RESPONSE, 0, content); + return null; + } else if (type == MSG_TIME_REQUEST) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); @@ -537,44 +542,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeByte(calendar.get(Calendar.SECOND)); sendResponse(channel, false, MSG_TIME_REQUEST, 0, content); - } else if (type == MSG_X1_GPS || type == MSG_X1_PHOTO_INFO) { - - return decodeX1(channel, buf, deviceSession, type); - - } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - - return decodeWifi(channel, buf, deviceSession, type); - - } else if (type == MSG_INFO) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_POWER, buf.readShort() * 0.01); - - return position; - - } else { - - return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - - } - - return null; - } - - private Object decodeX1(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { - - if (type == MSG_X1_GPS) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_X1_GPS) { buf.readUnsignedInt(); // data and alarm - decodeGps(position, buf, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); buf.readUnsignedShort(); // terminal info @@ -618,103 +592,111 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { photos.put(pictureId, photo); sendPhotoRequest(channel, pictureId); - } - - return null; - } + return null; - private Object decodeWifi(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + ByteBuf time = buf.readSlice(6); + DateBuilder dateBuilder = new DateBuilder() + .setYear(BcdUtil.readInteger(time, 2)) + .setMonth(BcdUtil.readInteger(time, 2)) + .setDay(BcdUtil.readInteger(time, 2)) + .setHour(BcdUtil.readInteger(time, 2)) + .setMinute(BcdUtil.readInteger(time, 2)) + .setSecond(BcdUtil.readInteger(time, 2)); + getLastLocation(position, dateBuilder.getDate()); - ByteBuf time = buf.readSlice(6); - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(time, 2)) - .setMonth(BcdUtil.readInteger(time, 2)) - .setDay(BcdUtil.readInteger(time, 2)) - .setHour(BcdUtil.readInteger(time, 2)) - .setMinute(BcdUtil.readInteger(time, 2)) - .setSecond(BcdUtil.readInteger(time, 2)); - getLastLocation(position, dateBuilder.getDate()); - - Network network = new Network(); - - int wifiCount; - if (type == MSG_WIFI_4) { - wifiCount = buf.readUnsignedByte(); - } else { - wifiCount = buf.getUnsignedByte(2); - } + Network network = new Network(); - for (int i = 0; i < wifiCount; i++) { + int wifiCount; if (type == MSG_WIFI_4) { - buf.skipBytes(2); + wifiCount = buf.readUnsignedByte(); + } else { + wifiCount = buf.getUnsignedByte(2); } - WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); - wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); - if (type != MSG_WIFI_4) { - wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + + for (int i = 0; i < wifiCount; i++) { + if (type == MSG_WIFI_4) { + buf.skipBytes(2); + } + WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); + wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); + if (type != MSG_WIFI_4) { + wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + } + network.addWifiAccessPoint(wifiAccessPoint); } - network.addWifiAccessPoint(wifiAccessPoint); - } - if (type != MSG_WIFI_4) { + if (type != MSG_WIFI_4) { - int cellCount = buf.readUnsignedByte(); - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); - } + int cellCount = buf.readUnsignedByte(); + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); + } + + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeShort(0x7878); + response.writeByte(0); + response.writeByte(type); + response.writeBytes(time.resetReaderIndex()); + response.writeByte('\r'); + response.writeByte('\n'); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(0x7878); - response.writeByte(0); - response.writeByte(type); - response.writeBytes(time.resetReaderIndex()); - response.writeByte('\r'); - response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } - } + position.setNetwork(network); - position.setNetwork(network); + return position; - return position; - } + } else if (type == MSG_INFO) { - private Object decodeBasicOther( - Channel channel, ByteBuf buf, DeviceSession deviceSession, int type, int dataLength) { + getLastLocation(position, null); - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_POWER, buf.readShort() * 0.01); + + return position; + + } else if (type == MSG_LBS_MULTIPLE_3 && variant == Variant.SR411_MINI) { + + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); - if (type == MSG_LBS_STATUS && dataLength >= 18) { + decodeLbs(position, buf, type, false); - return null; // space10x multi-lbs message + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + + return position; - } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_EXTEND - || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { + } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 + || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 + || type == MSG_WIFI_3 || type == MSG_WIFI_5) { boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); + if (variant == Variant.WANWAY_S20) { + buf.readUnsignedByte(); // ta + } + int mcc = buf.readUnsignedShort(); int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - int cellCount = type == MSG_WIFI_5 ? 6 : 7; + int cellCount = variant == Variant.WANWAY_S20 ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; for (int i = 0; i < cellCount; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); @@ -724,9 +706,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - buf.readUnsignedByte(); // time leads + if (variant != Variant.WANWAY_S20) { + buf.readUnsignedByte(); // ta + } - if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_2) { + if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_MULTIPLE_3 + && type != MSG_LBS_2) { int wifiCount = buf.readUnsignedByte(); for (int i = 0; i < wifiCount; i++) { String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); @@ -753,7 +738,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - } else if (type == MSG_BMS || type == MSG_BMS_2) { + } else if (type == MSG_BMS) { buf.skipBytes(8); // serial number @@ -785,20 +770,144 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_STATUS && buf.readableBytes() == 22) { + + getLastLocation(position, null); + + buf.readUnsignedByte(); // information content + buf.readUnsignedShort(); // satellites + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // language + + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // working mode + buf.readUnsignedShort(); // working voltage + buf.readUnsignedByte(); // reserved + buf.readUnsignedShort(); // working times + buf.readUnsignedShort(); // working time + + int value = buf.readUnsignedShort(); + double temperature = BitUtil.to(value, 15) * 0.1; + position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); + } else if (isSupported(type)) { - if (type == MSG_STATUS && buf.readableBytes() == 22) { - decodeHeartbeat(buf, position); + if (type == MSG_LBS_STATUS && variant == Variant.SPACE10X) { + return null; // multi-lbs message + } + + if (hasGps(type)) { + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { - decodeBasicUniversal(buf, deviceSession, type, position); + getLastLocation(position, null); + } + + if (hasLbs(type) && buf.readableBytes() > 6) { + decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); + } + + if (hasStatus(type)) { + decodeStatus(position, buf); + if (variant == Variant.OBD6) { + int signal = buf.readUnsignedShort(); + int satellites = BitUtil.between(signal, 10, 15) + BitUtil.between(signal, 5, 10); + position.set(Position.KEY_SATELLITES, satellites); + position.set(Position.KEY_RSSI, BitUtil.to(signal, 5)); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // language + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + buf.readUnsignedByte(); // working mode + position.set(Position.KEY_POWER, buf.readUnsignedShort() / 100.0); + } else { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } + } + + if (type == MSG_GPS_LBS_1) { + if (variant == Variant.GT06E_CARD) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // swiped + position.set("driverLicense", data.trim()); + } else if (variant == Variant.BENWAY) { + int mask = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); + if (BitUtil.check(mask, 8 + 4)) { + int value = BitUtil.to(mask, 8 + 1); + if (BitUtil.check(mask, 8 + 1)) { + value = -value; + } + position.set(Position.PREFIX_TEMP + 1, value); + } else { + int value = BitUtil.to(mask, 8 + 2); + if (BitUtil.check(mask, 8 + 5)) { + position.set(Position.PREFIX_ADC + 1, value); + } else { + position.set(Position.PREFIX_ADC + 1, value * 0.1); + } + } + } else if (variant == Variant.VXT01) { + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + buf.readUnsignedByte(); // alarm extension + } else if (variant == Variant.S5) { + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + position.set("oil", buf.readUnsignedShort()); + int temperature = buf.readUnsignedByte(); + if (BitUtil.check(temperature, 7)) { + temperature = -BitUtil.to(temperature, 7); + } + position.set(Position.PREFIX_TEMP + 1, temperature); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); + } + } + + if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) + && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + + if (type == MSG_GPS_LBS_3) { + int module = buf.readUnsignedShort(); + int subLength = buf.readUnsignedByte(); + switch (module) { + case 0x0027: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + break; + case 0x002E: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + break; + case 0x003B: + position.setAccuracy(buf.readUnsignedShort() * 0.01); + break; + default: + buf.skipBytes(subLength); + break; + } + } + + if (buf.readableBytes() == 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } } else if (type == MSG_ALARM) { + boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { - decodeGps(position, buf, false, false, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, false, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); @@ -830,6 +939,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); break; } + } else { if (dataLength > 0) { @@ -855,114 +965,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private void decodeHeartbeat(ByteBuf buf, Position position) { - - getLastLocation(position, null); - - buf.readUnsignedByte(); // information content - buf.readUnsignedShort(); // satellites - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // language - - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // working mode - buf.readUnsignedShort(); // working voltage - buf.readUnsignedByte(); // reserved - buf.readUnsignedShort(); // working times - buf.readUnsignedShort(); // working time - - int value = buf.readUnsignedShort(); - double temperature = BitUtil.to(value, 15) * 0.1; - position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); - - } - - private void decodeBasicUniversal(ByteBuf buf, DeviceSession deviceSession, int type, Position position) { - - if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); - } else { - getLastLocation(position, null); - } - - if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); - } - - if (hasStatus(type)) { - decodeStatus(position, buf, true); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() > 75 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // swiped - position.set("driverLicense", data.trim()); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 18) { - decodeStatus(position, buf, false); - position.set("oil", buf.readUnsignedShort()); - int temperature = buf.readUnsignedByte(); - if (BitUtil.check(temperature, 7)) { - temperature = -BitUtil.to(temperature, 7); - } - position.set(Position.PREFIX_TEMP + 1, temperature); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 2 + 6) { - int mask = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); - if (BitUtil.check(mask, 8 + 4)) { - int value = BitUtil.to(mask, 8 + 1); - if (BitUtil.check(mask, 8 + 1)) { - value = -value; - } - position.set(Position.PREFIX_TEMP + 1, value); - } else { - int value = BitUtil.to(mask, 8 + 2); - if (BitUtil.check(mask, 8 + 5)) { - position.set(Position.PREFIX_ADC + 1, value); - } else { - position.set(Position.PREFIX_ADC + 1, value * 0.1); - } - } - } - - if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) && buf.readableBytes() >= 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } - - if (type == MSG_GPS_LBS_3) { - int module = buf.readUnsignedShort(); - int length = buf.readUnsignedByte(); - switch (module) { - case 0x0027: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 0x002E: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - case 0x003B: - position.setAccuracy(buf.readUnsignedShort() * 0.01); - break; - default: - buf.skipBytes(length); - break; - } - } - - if (buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - } - private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); @@ -970,8 +972,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); @@ -990,7 +992,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); } - if (decodeLocationString(position, data) == null) { + Parser parser = new Parser(PATTERN_LOCATION, data); + + if (parser.matches()) { + position.setValid(true); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setCourse(parser.nextDouble()); + position.setSpeed(parser.nextDouble()); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); + } else { getLastLocation(position, null); position.set(Position.KEY_RESULT, data); } @@ -1004,31 +1015,62 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); if (subType == 0x00) { + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01); return position; + } else if (subType == 0x05) { + + if (buf.readableBytes() >= 6 + 1 + 6) { + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setDeviceTime(dateBuilder.getDate()); + } + int flags = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; + } else if (subType == 0x0a) { + buf.skipBytes(8); // imei buf.skipBytes(8); // imsi position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10)).replaceAll("f", "")); return position; + } else if (subType == 0x0d) { + if (buf.getByte(buf.readerIndex()) != '!') { buf.skipBytes(6); } - return decodeFuelData(position, buf.toString( + + Parser parser = new Parser(PATTERN_FUEL, buf.toString( buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); + if (!parser.matches()) { + return null; + } + + position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); + position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); + + return position; + } else if (subType == 0x1b) { - buf.readUnsignedByte(); // header - buf.readUnsignedByte(); // type - position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); - buf.readUnsignedByte(); // checksum - buf.readUnsignedByte(); // footer + + if (Character.isLetter(buf.getUnsignedByte(buf.readerIndex()))) { + String data = buf.readCharSequence(buf.readableBytes() - 6, StandardCharsets.US_ASCII).toString(); + position.set("serial", data.trim()); + } else { + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // type + position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); + buf.readUnsignedByte(); // checksum + buf.readUnsignedByte(); // footer + } return position; + } } else if (type == MSG_X1_PHOTO_DATA) { @@ -1043,15 +1085,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set( - Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { - if (!decodeGps(position, buf, true, deviceSession.getTimeZone())) { + if (!decodeGps(position, buf, true, deviceSession.get(DeviceSession.KEY_TIMEZONE))) { getLastLocation(position, position.getDeviceTime()); } @@ -1096,7 +1136,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_OBD) { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); @@ -1143,132 +1183,111 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - return decodeExtendedModular(channel, buf, deviceSession); - - } else { - - return decodeExtendedOther(channel, buf, deviceSession, type); - - } - - return null; - } - - private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - while (buf.readableBytes() > 6) { - int moduleType = buf.readUnsignedShort(); - int moduleLength = buf.readUnsignedShort(); - - switch (moduleType) { - case 0x03: - position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); - break; - case 0x09: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x0a: - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - break; - case 0x11: - CellTower cellTower = CellTower.from( - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedMedium(), - buf.readUnsignedByte()); - if (cellTower.getCellId() > 0) { - position.setNetwork(new Network(cellTower)); - } - break; - case 0x18: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - break; - case 0x28: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x29: - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); - break; - case 0x2a: - int input = buf.readUnsignedByte(); - position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); - position.set("tamper", BitUtil.from(input, 4) > 0); - break; - case 0x2b: - int event = buf.readUnsignedByte(); - switch (event) { - case 0x11: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 0x12: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 0x13: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 0x14: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - default: - break; - } - position.set(Position.KEY_EVENT, event); - break; - case 0x2e: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0x33: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.setAltitude(buf.readShort()); - - double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; - double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - int flags = buf.readUnsignedShort(); - position.setCourse(BitUtil.to(flags, 10)); - position.setValid(BitUtil.check(flags, 12)); + while (buf.readableBytes() > 6) { + int moduleType = buf.readUnsignedShort(); + int moduleLength = buf.readUnsignedShort(); - if (!BitUtil.check(flags, 10)) { - latitude = -latitude; - } - if (BitUtil.check(flags, 11)) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - break; - case 0x34: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - buf.readUnsignedIntLE(); // time - buf.skipBytes(buf.readUnsignedByte()); // content - break; - default: - buf.skipBytes(moduleLength); - break; + switch (moduleType) { + case 0x03: + position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); + break; + case 0x09: + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + break; + case 0x0a: + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); + break; + case 0x11: + CellTower cellTower = CellTower.from( + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedMedium(), + buf.readUnsignedByte()); + if (cellTower.getCellId() > 0) { + position.setNetwork(new Network(cellTower)); + } + break; + case 0x18: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + break; + case 0x28: + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + break; + case 0x29: + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + break; + case 0x2a: + int input = buf.readUnsignedByte(); + position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); + position.set("tamper", BitUtil.from(input, 4) > 0); + break; + case 0x2b: + int event = buf.readUnsignedByte(); + switch (event) { + case 0x11: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case 0x12: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + case 0x13: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case 0x14: + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); + break; + case 0x2e: + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + break; + case 0x33: + position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.setAltitude(buf.readShort()); + + double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; + double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + int flags = buf.readUnsignedShort(); + position.setCourse(BitUtil.to(flags, 10)); + position.setValid(BitUtil.check(flags, 12)); + + if (!BitUtil.check(flags, 10)) { + latitude = -latitude; + } + if (BitUtil.check(flags, 11)) { + longitude = -longitude; + } + + position.setLatitude(latitude); + position.setLongitude(longitude); + break; + case 0x34: + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + buf.readUnsignedIntLE(); // time + buf.skipBytes(buf.readUnsignedByte()); // content + break; + default: + buf.skipBytes(moduleLength); + break; + } } - } - - if (position.getFixTime() == null) { - getLastLocation(position, null); - } - - sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - return position; - } + if (position.getFixTime() == null) { + getLastLocation(position, null); + } - private Object decodeExtendedOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - Position position = null; + return position; - if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { + } else if (type == MSG_MULTIMEDIA) { buf.skipBytes(8); // serial number long timestamp = buf.readUnsignedInt() * 1000; @@ -1301,9 +1320,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, - Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } } @@ -1343,21 +1360,56 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } + private void decodeVariant(ByteBuf buf) { + int header = buf.getUnsignedShort(buf.readerIndex()); + int length; + int type; + if (header == 0x7878) { + length = buf.getUnsignedByte(buf.readerIndex() + 2); + type = buf.getUnsignedByte(buf.readerIndex() + 2 + 1); + } else { + length = buf.getUnsignedShort(buf.readerIndex() + 2); + type = buf.getUnsignedByte(buf.readerIndex() + 2 + 2); + } + + if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x24) { + variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { + variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { + variant = Variant.WANWAY_S20; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x2e) { + variant = Variant.SR411_MINI; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length >= 0x71) { + variant = Variant.GT06E_CARD; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x21) { + variant = Variant.BENWAY; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x2b) { + variant = Variant.S5; + } else if (header == 0x7878 && type == MSG_LBS_STATUS && length >= 0x17) { + variant = Variant.SPACE10X; + } else if (header == 0x7878 && type == MSG_STATUS && length == 0x13) { + variant = Variant.OBD6; + } else { + variant = Variant.STANDARD; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; + decodeVariant(buf); + int header = buf.readShort(); if (header == 0x7878) { return decodeBasic(channel, remoteAddress, buf); - } else if (header == 0x7979) { + } else { return decodeExtended(channel, remoteAddress, buf); } - - return null; } } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 9115ba10f..dc5dd446f 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,12 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; @@ -33,8 +35,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, String content) { - boolean language = Context.getIdentityManager() - .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); + boolean language = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_LANGUAGE.withPrefix(getProtocolName()), deviceId); ByteBuf buf = Unpooled.buffer(); @@ -43,7 +45,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(1 + 1 + 4 + content.length() + 2 + 2 + (language ? 2 : 0)); // message length - buf.writeByte(0x80); // message type + buf.writeByte(Gt06ProtocolDecoder.MSG_COMMAND_0); buf.writeByte(4 + content.length()); // command length buf.writeInt(0); @@ -66,19 +68,31 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); + + String password = AttributeUtil.getDevicePassword( + getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); - String password = Context.getIdentityManager() - .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); + Device device = getCacheManager().getObject(Device.class, command.getDeviceId()); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), - alternative ? "DYD," + password + "#" : "Relay,1#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "DYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "DYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,1#"); + } case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), - alternative ? "HFYD," + password + "#" : "Relay,0#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "HFYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "HFYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,0#"); + } case Command.TYPE_CUSTOM: return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); default: diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index aa4ad20b1..6b79ba58b 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Gt30Protocol extends BaseProtocol { - public Gt30Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt30Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java index abf208a46..fb3a2b8ae 100644 --- a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index a5246abc6..4e5f8c96a 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -17,15 +17,18 @@ package org.traccar.protocol; import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; +import javax.inject.Inject; + public class H02Protocol extends BaseProtocol { - public H02Protocol() { + @Inject + public H02Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, @@ -33,19 +36,19 @@ public class H02Protocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_POSITION_PERIODIC ); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - int messageLength = Context.getConfig().getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + int messageLength = config.getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); pipeline.addLast(new H02FrameDecoder(messageLength)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index dd7141a2c..2ad4f644b 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -176,17 +175,19 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // coding scheme .groupEnd() .groupBegin() - .number("-(d+)-(d+.d+),") // latitude + .number("-(d+)-(d+.d+),([NS]),") // latitude .or() - .number("(d+)(dd.d+),") // latitude + .number("(d+)(dd.d+),([NS]),") // latitude + .or() + .number("(d+)(dd)(d{4}),([NS]),") // latitude .groupEnd() - .expression("([NS]),") .groupBegin() - .number("-(d+)-(d+.d+),") // longitude + .number("-(d+)-(d+.d+),([EW]),") // longitude .or() - .number("(d+)(dd.d+),") // longitude + .number("(d+)(dd.d+),([EW]),") // longitude + .or() + .number("(d+)(dd)(d{4}),([EW]),") // longitude .groupEnd() - .expression("([EW]),") .number(" *(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(?:d+,)?") // battery @@ -332,7 +333,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext() && parser.next().equals("V1")) { sendResponse(channel, remoteAddress, id, "V1"); - } else if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + } else if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { sendResponse(channel, remoteAddress, id, "R12"); } @@ -349,19 +350,25 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setValid(true); } - if (parser.hasNext(2)) { - position.setLatitude(-parser.nextCoordinate()); + if (parser.hasNext(3)) { + position.setLatitude(parser.nextCoordinate()); } - if (parser.hasNext(2)) { + if (parser.hasNext(3)) { position.setLatitude(parser.nextCoordinate()); } + if (parser.hasNext(4)) { + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + } - if (parser.hasNext(2)) { - position.setLongitude(-parser.nextCoordinate()); + if (parser.hasNext(3)) { + position.setLongitude(parser.nextCoordinate()); } - if (parser.hasNext(2)) { + if (parser.hasNext(3)) { position.setLongitude(parser.nextCoordinate()); } + if (parser.hasNext(4)) { + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + } position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); @@ -384,7 +391,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextInt(0)); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } if (parser.hasNext()) { diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 7a765332c..86b8c80d4 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,10 +16,11 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Date; @@ -59,8 +60,9 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { return formatCommand(time, uniqueId, "S20", "1", "0"); case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { + if (AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), + command.getDeviceId())) { return formatCommand(time, uniqueId, "D1", frequency); } else { return formatCommand(time, uniqueId, "S71", "22", frequency); diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index 6e5760bd4..f56c605f0 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class HaicomProtocol extends BaseProtocol { - public HaicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HaicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java index dd20f2aeb..9903e7735 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index 34dbf0f51..aa2d7d852 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class HomtecsProtocol extends BaseProtocol { - public HomtecsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public HomtecsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new HomtecsProtocolDecoder(HomtecsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java index a93572b5c..5541cb065 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 387b967d3..02d8e5a8e 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class HoopoProtocol extends BaseProtocol { - public HoopoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HoopoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index 5db7f0bc0..708c74f2a 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; @@ -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); @@ -62,6 +62,10 @@ public class HoopoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, eventData.getString("eventType")); position.set(Position.KEY_BATTERY_LEVEL, eventData.getInt("batteryLevel")); + if (json.containsKey("movement")) { + position.setSpeed(json.getJsonObject("movement").getInt("Speed")); + } + return position; } diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index 103f2d501..b1b61e977 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class HuaShengProtocol extends BaseProtocol { - public HuaShengProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HuaShengProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); pipeline.addLast(new HuaShengProtocolDecoder(HuaShengProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 891046213..371691d82 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 791672b85..c37918b0e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -18,17 +18,21 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class HuabaoProtocol extends BaseProtocol { - public HuabaoProtocol() { + @Inject + public HuabaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new HuabaoProtocolEncoder(HuabaoProtocol.this)); pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 871410c44..d0bbeebb5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -34,7 +34,10 @@ 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.Calendar; +import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; @@ -48,11 +51,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GENERAL_RESPONSE = 0x8001; public static final int MSG_GENERAL_RESPONSE_2 = 0x4401; public static final int MSG_HEARTBEAT = 0x0002; + public static final int MSG_HEARTBEAT_2 = 0x0506; public static final int MSG_TERMINAL_REGISTER = 0x0100; public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100; public static final int MSG_TERMINAL_CONTROL = 0x8105; public static final int MSG_TERMINAL_AUTH = 0x0102; public static final int MSG_LOCATION_REPORT = 0x0200; + public static final int MSG_LOCATION_BATCH_2 = 0x0210; public static final int MSG_ACCELERATION = 0x2070; public static final int MSG_LOCATION_REPORT_2 = 0x5501; public static final int MSG_LOCATION_REPORT_BLIND = 0x5502; @@ -61,6 +66,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TIME_SYNC_REQUEST = 0x0109; public static final int MSG_TIME_SYNC_RESPONSE = 0x8109; public static final int MSG_PHOTO = 0x8888; + public static final int MSG_TRANSPARENT = 0x0900; public static final int RESULT_SUCCESS = 0; @@ -119,6 +125,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { return Position.ALARM_FAULT; } + if (BitUtil.check(value, 7) || BitUtil.check(value, 18)) { + return Position.ALARM_LOW_BATTERY; + } if (BitUtil.check(value, 8)) { return Position.ALARM_POWER_OFF; } @@ -142,6 +151,28 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15); } + private Date readDate(ByteBuf buf, TimeZone timeZone) { + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setYear(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setDay(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)); + return dateBuilder.getDate(); + } + + private String decodeId(ByteBuf id) { + String serial = ByteBufUtil.hexDump(id); + if (serial.matches("[0-9]+")) { + return serial; + } else { + long imei = id.getUnsignedShort(0); + imei = (imei << 32) + id.getUnsignedInt(2); + return String.valueOf(imei); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -149,7 +180,19 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; if (buf.getByte(buf.readerIndex()) == '(') { - return decodeResult(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)); + String sentence = buf.toString(StandardCharsets.US_ASCII); + if (sentence.contains("BASE,2")) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String response = sentence.replace("TIME", dateFormat.format(new Date())); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer(response, StandardCharsets.US_ASCII), remoteAddress)); + } + return null; + } else { + return decodeResult(channel, remoteAddress, sentence); + } } buf.readUnsignedByte(); // start marker @@ -163,13 +206,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { index = buf.readUnsignedShort(); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, decodeId(id)); if (deviceSession == null) { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId(), "GMT+8")); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId(), "GMT+8")); } if (type == MSG_TERMINAL_REGISTER) { @@ -178,12 +221,12 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeByte(RESULT_SUCCESS); - response.writeBytes(ByteBufUtil.hexDump(id).getBytes(StandardCharsets.US_ASCII)); + response.writeBytes(decodeId(id).getBytes(StandardCharsets.US_ASCII)); channel.writeAndFlush(new NetworkMessage( formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_HEARTBEAT_2 || type == MSG_PHOTO) { sendGeneralResponse(channel, remoteAddress, id, type, index); @@ -201,11 +244,11 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return decodeLocation2(deviceSession, buf, type); - } else if (type == MSG_LOCATION_BATCH) { + } else if (type == MSG_LOCATION_BATCH || type == MSG_LOCATION_BATCH_2) { sendGeneralResponse(channel, remoteAddress, id, type, index); - return decodeLocationBatch(deviceSession, buf); + return decodeLocationBatch(deviceSession, buf, type); } else if (type == MSG_TIME_SYNC_REQUEST) { @@ -249,6 +292,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_TRANSPARENT) { + + return decodeTransparent(deviceSession, buf); + } return null; @@ -266,17 +313,83 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + private void decodeExtension(Position position, ByteBuf buf, int endIndex) { + while (buf.readerIndex() < endIndex) { + int type = buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (type) { + case 0x01: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100L); + break; + case 0x02: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); + break; + case 0x03: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x80: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + break; + case 0x81: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x82: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); + break; + case 0x83: + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + break; + case 0x84: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + break; + case 0x85: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort()); + break; + case 0x86: + position.set("intakeTemp", buf.readUnsignedByte() - 40); + break; + case 0x87: + position.set("intakeFlow", buf.readUnsignedShort()); + break; + case 0x88: + position.set("intakePressure", buf.readUnsignedByte()); + break; + case 0x89: + position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + break; + case 0x8B: + position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); + break; + case 0x8C: + position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100L); + break; + case 0x8D: + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 1000L); + break; + case 0x8E: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + break; + case 0xA0: + String codes = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set(Position.KEY_DTCS, codes.replace(',', ' ')); + break; + case 0xCC: + position.set(Position.KEY_ICCID, buf.readCharSequence(20, StandardCharsets.US_ASCII).toString()); + break; + default: + buf.skipBytes(length); + break; + } + } + } - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + private void decodeCoordinates(Position position, ByteBuf buf) { int status = buf.readInt(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); position.set(Position.KEY_BLOCKED, BitUtil.check(status, 10)); + position.set(Position.KEY_CHARGE, BitUtil.check(status, 26)); position.setValid(BitUtil.check(status, 1)); @@ -294,19 +407,28 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else { position.setLongitude(lon); } + } + + private double decodeCustomDouble(ByteBuf buf) { + int b1 = buf.readByte(); + int b2 = buf.readUnsignedByte(); + int sign = b1 != 0 ? b1 / Math.abs(b1) : 1; + return sign * (Math.abs(b1) + b2 / 255.0); + } + + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + + decodeCoordinates(position, buf); position.setAltitude(buf.readShort()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort()); - - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); + position.setTime(readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE))); if (buf.readableBytes() == 20) { @@ -333,6 +455,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x02: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); break; + case 0x2b: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + break; case 0x30: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; @@ -346,6 +471,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()); @@ -383,11 +513,21 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); break; case 0xD4: - case 0xFE: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + if (length == 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + } else { + int count = buf.readUnsignedByte(); + for (int i = 1; i <= count; i++) { + position.set("lock" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Card", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Battery", buf.readUnsignedByte()); + int status = buf.readUnsignedShort(); + position.set("lock" + i + "Locked", !BitUtil.check(status, 5)); + } + } break; case 0xDA: buf.readUnsignedShort(); // string cut count @@ -396,6 +536,14 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, BitUtil.check(deviceStatus, 2)); position.set("cover", BitUtil.check(deviceStatus, 3)); break; + case 0xE6: + while (buf.readerIndex() < endIndex) { + int sensorIndex = buf.readUnsignedByte(); + buf.skipBytes(6); // mac + position.set(Position.PREFIX_TEMP + sensorIndex, decodeCustomDouble(buf)); + position.set("humidity" + sensorIndex, decodeCustomDouble(buf)); + } + break; case 0xEB: if (buf.getUnsignedShort(buf.readerIndex()) > 200) { Network network = new Network(); @@ -423,6 +571,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x00CE: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0x00D8: + Network network = new Network(); + network.addCellTower(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedByte(), + buf.readUnsignedShort(), buf.readUnsignedInt())); + position.setNetwork(network); + break; + case 0xE1: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.skipBytes(extendedLength - 2); break; @@ -440,6 +598,105 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xF3: + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedShort(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x0002: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x0003: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x0004: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + break; + case 0x0005: + position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0007: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.1); + break; + case 0x0008: + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedShort() * 0.1); + break; + case 0x0009: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShort() - 40); + break; + case 0x000B: + position.set("intakePressure", buf.readUnsignedShort()); + break; + case 0x000C: + position.set("intakeTemp", buf.readUnsignedShort() - 40); + break; + case 0x000D: + position.set("intakeFlow", buf.readUnsignedShort()); + break; + case 0x000E: + position.set(Position.KEY_THROTTLE, buf.readUnsignedShort() * 100 / 255); + break; + case 0x0050: + position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); + break; + case 0x0100: + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 0.1); + break; + case 0x0102: + position.set("tripFuel", buf.readUnsignedShort() * 0.1); + break; + case 0x0112: + position.set("hardAccelerationCount", buf.readUnsignedShort()); + break; + case 0x0113: + position.set("hardDecelerationCount", buf.readUnsignedShort()); + break; + case 0x0114: + position.set("hardCorneringCount", buf.readUnsignedShort()); + break; + default: + buf.skipBytes(extendedLength); + break; + } + } + break; + case 0xFE: + if (length == 1) { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } else { + int mark = buf.readUnsignedByte(); + if (mark == 0x7C) { + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedByte(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x01: + long alarms = buf.readUnsignedInt(); + if (BitUtil.check(alarms, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + } + if (BitUtil.check(alarms, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } + if (BitUtil.check(alarms, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + if (BitUtil.check(alarms, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + } + if (BitUtil.check(alarms, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + break; + default: + buf.skipBytes(extendedLength); + break; + } + } + } + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } + break; default: break; } @@ -468,7 +725,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, true); } - position.setNetwork(new Network(CellTower.fromCidLac(buf.readUnsignedInt(), buf.readUnsignedShort()))); + position.setNetwork(new Network(CellTower.fromCidLac( + getConfig(), buf.readUnsignedInt(), buf.readUnsignedShort()))); int product = buf.readUnsignedByte(); int status = buf.readUnsignedShort(); @@ -496,24 +754,141 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; } - private List<Position> decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf) { + private List<Position> decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf, int type) { List<Position> positions = new LinkedList<>(); - int count = buf.readUnsignedShort(); - int locationType = buf.readUnsignedByte(); + int locationType = 0; + if (type == MSG_LOCATION_BATCH) { + buf.readUnsignedShort(); // count + locationType = buf.readUnsignedByte(); + } - for (int i = 0; i < count; i++) { - int endIndex = buf.readUnsignedShort() + buf.readerIndex(); - Position position = decodeLocation(deviceSession, buf); - if (locationType == 0) { + while (buf.readableBytes() > 2) { + int length = type == MSG_LOCATION_BATCH_2 ? buf.readUnsignedByte() : buf.readUnsignedShort(); + ByteBuf fragment = buf.readSlice(length); + Position position = decodeLocation(deviceSession, fragment); + if (locationType > 0) { position.set(Position.KEY_ARCHIVE, true); } positions.add(position); - buf.readerIndex(endIndex); } return positions; } + private Position decodeTransparent(DeviceSession deviceSession, ByteBuf buf) { + + int type = buf.readUnsignedByte(); + + if (type == 0xF0) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + Date time = readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE)); + + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_ARCHIVE, true); + } + + buf.readUnsignedByte(); // vehicle type + + int count; + int subtype = buf.readUnsignedByte(); + switch (subtype) { + case 0x01: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x0102: + case 0x0528: + case 0x0546: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0103: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedInt() * 0.01); + break; + case 0x052A: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.01); + break; + case 0x0105: + case 0x052C: + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.01); + break; + case 0x014A: + case 0x0537: + case 0x0538: + case 0x0539: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); + break; + default: + switch (length) { + case 1: + position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); + break; + case 2: + position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); + break; + case 4: + position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); + break; + default: + buf.skipBytes(length); + break; + } + break; + } + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x03: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x1A: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 0x1B: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 0x1C: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + case 0x1D: + case 0x1E: + case 0x1F: + position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + break; + case 0x23: + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + break; + default: + break; + } + buf.skipBytes(length); + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x0B: + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); + } + getLastLocation(position, time); + break; + default: + return null; + } + + return position; + } + + return null; + } + } diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 55c1e0c3b..ada7e3fba 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -18,10 +18,11 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; import java.text.SimpleDateFormat; import java.util.Date; @@ -35,8 +36,8 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); ByteBuf id = Unpooled.wrappedBuffer( DataConverter.parseHex(getUniqueId(command.getDeviceId()))); diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index 9f6424a57..ed4289d73 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class HunterProProtocol extends BaseProtocol { - public HunterProProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HunterProProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java index 06bc12d59..eada1fd9a 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index 418178756..aa1f4ff5b 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class IdplProtocol extends BaseProtocol { - public IdplProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IdplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java index cf3c03d7f..72409b168 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index 3abf40da7..b1a91cca9 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class IntellitracProtocol extends BaseProtocol { - public IntellitracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IntellitracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new IntellitracFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java index 930d4f23b..b86584016 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index f202d9b9d..0d288f4bf 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.mqtt.MqttEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class IotmProtocol extends BaseProtocol { - public IotmProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IotmProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(MqttEncoder.INSTANCE); pipeline.addLast(new MqttDecoder()); pipeline.addLast(new IotmProtocolDecoder(IotmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index 9c94ffd4b..7bbe6c8de 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import io.netty.handler.codec.mqtt.MqttMessageBuilders; import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttSubscribeMessage; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; @@ -260,7 +260,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { MqttSubscribeMessage message = (MqttSubscribeMessage) msg; MqttMessage response = MqttMessageBuilders.subAck() - .packetId((short) message.variableHeader().messageId()) + .packetId(message.variableHeader().messageId()) .build(); if (channel != null) { @@ -339,7 +339,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // checksum MqttMessage response = MqttMessageBuilders.pubAck() - .packetId((short) message.variableHeader().packetId()) + .packetId(message.variableHeader().packetId()) .build(); if (channel != null) { diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 45df3da11..5148e8ab0 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -20,17 +20,21 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class ItsProtocol extends BaseProtocol { - public ItsProtocol() { + @Inject + public ItsProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ItsFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 9eed58347..8a8d734cf 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; @@ -205,7 +205,8 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.setValid(parser.nextInt() == 1); } - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setTime(parser.nextDateTime( + Parser.DateTimeFormat.DMY_HMS, getTimeZone(deviceSession.getDeviceId()).getID())); if (parser.hasNext()) { position.setValid(parser.next().matches("[1A]")); } diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index fb44e4fe9..763457641 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -20,13 +20,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Ivt401Protocol extends BaseProtocol { - public Ivt401Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ivt401Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Ivt401ProtocolDecoder(Ivt401Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java index 63556e7a9..972f22ebe 100644 --- a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java new file mode 100644 index 000000000..78aa6c81c --- /dev/null +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class JidoProtocol extends BaseProtocol { + + @Inject + public JidoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new JidoProtocolDecoder(JidoProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java new file mode 100644 index 000000000..98fb36e11 --- /dev/null +++ b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java @@ -0,0 +1,128 @@ +/* + * 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.session.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 JidoProtocolDecoder extends BaseProtocolDecoder { + + public JidoProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("*") + .number("(d+),") // imei + .number("(d+),") // command + .expression("([AV]),").optional() // validity + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+)(dd.d+),") // latitude + .expression("([NS]),") + .number("(d+)(dd.d+),") // longitude + .expression("([EW]),") + .groupBegin() + .number("(d+),") // speed + .number("(d+),") // odometer + .number("(d+),") // course + .number("(-?d+),") // altitude + .number("(d+),") // satellites + .number("d+,") // gsm 1 + .number("d+,") // gsm 2 + .number("([01]),") // charging + .number("(d+),") // battery level + .expression("([YKN]),") // mode + .number("([01]),") // lock + .number("[^,]+,") // accelerometer x + .number("[^,]+,") // accelerometer y + .number("[^,]+,") // accelerometer z + .or() + .expression("[^,]*,") // data + .groupEnd() + .number("xx") // checksum + .compile(); + + private String decodeAlarm(int type) { + switch (type) { + case 3: + return Position.ALARM_LOW_BATTERY; + case 4: + return Position.ALARM_TAMPERING; + default: + return null; + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + 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())); + + if (parser.hasNext()) { + position.setValid(parser.next().equals("A")); + } else { + position.setValid(true); + } + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + + if (parser.hasNext(9)) { + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_ODOMETER, parser.nextInt()); + + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_CHARGE, parser.nextInt() > 0); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + position.set("mode", parser.next()); + position.set(Position.KEY_BLOCKED, parser.nextInt() > 0); + + } + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index fe5b2480d..30c8e9977 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -1,6 +1,6 @@ /* + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Nyash (nyashh@gmail.com) - * Copyright 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class JpKorjarProtocol extends BaseProtocol { - public JpKorjarProtocol() { - addServer(new TrackerServer(false, this.getName()) { + @Inject + public JpKorjarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JpKorjarFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new JpKorjarProtocolDecoder(JpKorjarProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java index 33026918a..ffddcc568 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 37c82f741..bf0b3379e 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -19,19 +19,23 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Jt600Protocol extends BaseProtocol { - public Jt600Protocol() { + @Inject + public Jt600Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP, Command.TYPE_SET_TIMEZONE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Jt600FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Jt600ProtocolEncoder(Jt600Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 37c1674d4..9ed44f565 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -141,7 +141,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length - while (buf.readableBytes() > 1) { + boolean responseRequired = false; + + while (buf.readableBytes() >= 17) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -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); @@ -172,7 +177,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, battery); } - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromCidLac( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); cellTower.setSignalStrength((int) buf.readUnsignedByte()); position.setNetwork(new Network(cellTower)); @@ -196,7 +202,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int rssi = buf.readUnsignedByte(); if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); + CellTower cellTower = CellTower.fromCidLac(getConfig(), cid, lac); cellTower.setSignalStrength(rssi); position.setNetwork(new Network(cellTower)); } else { @@ -232,7 +238,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; } @@ -343,7 +357,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); position.set(Position.KEY_STATUS, parser.nextBinInt(0)); - CellTower cellTower = CellTower.fromCidLac(parser.nextInt(0), parser.nextInt(0)); + CellTower cellTower = CellTower.fromCidLac(getConfig(), parser.nextInt(0), parser.nextInt(0)); cellTower.setSignalStrength(parser.nextInt(0)); position.setNetwork(new Network(cellTower)); @@ -361,6 +375,64 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_P45 = new PatternBuilder() + .text("(") + .number("(d+),") // id + .text("P45,") // type + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .expression("([AV]),") // validity + .number("(d+),") // speed + .number("(d+),") // course + .number("d+,") // event source + .number("d+,") // unlock verification + .number("(d+),") // rfid + .number("d+,") // password verification + .number("d+,") // incorrect password count + .number("(d+),") // index + .any() + .compile(); + + private Position decodeP45(String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_P45, 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.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setValid(parser.next().equals("A")); + + position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + String rfid = parser.next(); + if (!rfid.equals("0000000000")) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); + } + + int index = parser.nextInt(); + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage("(P69,0," + index + ")", remoteAddress)); + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -374,6 +446,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { String sentence = buf.toString(StandardCharsets.US_ASCII); if (sentence.contains("W01")) { return decodeW01(sentence, channel, remoteAddress); + } else if (sentence.contains("P45")) { + return decodeP45(sentence, channel, remoteAddress); } else { return decodeU01(sentence, channel, remoteAddress); } diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 90c0c511c..8d78c8c56 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -22,13 +22,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class KenjiProtocol extends BaseProtocol { - public KenjiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public KenjiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java index 63812242a..fb989c72e 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 60a2aea7f..521274de5 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -19,11 +19,15 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class KhdProtocol extends BaseProtocol { - public KhdProtocol() { + @Inject + public KhdProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, @@ -33,9 +37,9 @@ public class KhdProtocol extends BaseProtocol { Command.TYPE_SET_ODOMETER, Command.TYPE_POSITION_SINGLE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); pipeline.addLast(new KhdProtocolEncoder(KhdProtocol.this)); pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java index a14f9b8a4..d7c236c4f 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java index 8aeb9660d..12353b415 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java @@ -84,7 +84,7 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { return encodeCommand(MSG_FACTORY_RESET, uniqueId, null); case Command.TYPE_SET_SPEED_LIMIT: ByteBuf content = Unpooled.buffer(); - content.writeByte(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeByte(command.getInteger(Command.KEY_DATA)); return encodeCommand(MSG_RESUME_OIL, uniqueId, content); case Command.TYPE_SET_ODOMETER: return encodeCommand(MSG_DELETE_MILEAGE, uniqueId, null); diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 942029307..0edea6095 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class L100Protocol extends BaseProtocol { - public L100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public L100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new L100FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java index 5b5eb7d60..820de8f1c 100644 --- a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index 0a0499ad7..bbebd51ed 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class LacakProtocol extends BaseProtocol { - public LacakProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LacakProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java index 132087c8f..809fafc90 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 1d561dbd2..249d3bcbe 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -18,23 +18,27 @@ package org.traccar.protocol; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; -import org.traccar.model.Command; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; +import org.traccar.model.Command; + +import javax.inject.Inject; public class LaipacProtocol extends BaseProtocol { - public LaipacProtocol() { + @Inject + public LaipacProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 45890e9a2..e9570ee11 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,8 +17,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; @@ -253,8 +253,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); - String devicePassword = Context.getIdentityManager() - .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); + String devicePassword = AttributeUtil.getDevicePassword( + getCacheManager(), deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index 05f63a2d7..7e13e23d0 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -22,13 +22,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class LeafSpyProtocol extends BaseProtocol { - public LeafSpyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LeafSpyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java index ad0c9bd32..6affb85c5 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index 9de8526c3..a23ea0f57 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class M2cProtocol extends BaseProtocol { - public M2cProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2cProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java index 1460bb176..9415d0f07 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index dda328a59..6809d800c 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class M2mProtocol extends BaseProtocol { - public M2mProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2mProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(23)); pipeline.addLast(new M2mProtocolDecoder(M2mProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java index 21e4a2fd0..7eca93a59 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 87453ce7d..38a67f9a4 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MaestroProtocol extends BaseProtocol { - public MaestroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MaestroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(160)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java index 37b097414..78308658e 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 49d8b1e9f..492e86605 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ManPowerProtocol extends BaseProtocol { - public ManPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ManPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java index 2c7b7eb40..8ac13b4d4 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index d779648e4..cf65a2db3 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -15,18 +15,21 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import javax.inject.Inject; public class Mavlink2Protocol extends BaseProtocol { - public Mavlink2Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Mavlink2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 1, 10, 0)); pipeline.addLast(new Mavlink2ProtocolDecoder(Mavlink2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java index 431258388..fac930ba8 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index e9f5f9fde..10215eb7c 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MegastekProtocol extends BaseProtocol { - public MegastekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MegastekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MegastekFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java index 7233280c2..06b6f0e76 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index e8a66e49f..492094ce3 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -18,31 +18,36 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeiligaoProtocol extends BaseProtocol { - public MeiligaoProtocol() { + @Inject + public MeiligaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, + Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_GEOFENCE, Command.TYPE_SET_TIMEZONE, Command.TYPE_REQUEST_PHOTO, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoFrameDecoder()); pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index d38e5d1c3..f3b56973a 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -40,7 +39,7 @@ import java.util.regex.Pattern; public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { - private Map<Byte, ByteBuf> photos = new HashMap<>(); + private final Map<Byte, ByteBuf> photos = new HashMap<>(); public MeiligaoProtocolDecoder(Protocol protocol) { super(protocol); @@ -469,10 +468,9 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } else if (command == MSG_POSITION_IMAGE) { byte imageIndex = buf.readByte(); buf.readUnsignedByte(); // image upload type - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index e5b2cf4e7..5859d91ce 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +18,16 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; +import java.util.Set; import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @@ -56,15 +59,36 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { return buf; } - @Override - protected Object encodeCommand(Command command) { + private ByteBuf encodeOutputCommand(long deviceId, int index, int value) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + int outputCount; + int outputType; - int outputControlMessageType = alternative - ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 - : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + String model = getCacheManager().getObject(Device.class, deviceId).getModel(); + + if (model != null && Set.of("TK510", "GT08", "TK208", "TK228", "MT05").contains(model)) { + outputCount = 5; + outputType = MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1; + } else { + outputCount = 1; + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), deviceId); + outputType = alternative + ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 + : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + } + + ByteBuf content = Unpooled.buffer(); + + for (int i = 1; i <= outputCount; i++) { + content.writeByte(i == index ? value : 2); + } + + return encodeContent(deviceId, outputType, content); + } + + @Override + protected Object encodeCommand(Command command) { ByteBuf content = Unpooled.buffer(); @@ -74,12 +98,14 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_POSITION_PERIODIC: content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); + case Command.TYPE_OUTPUT_CONTROL: + int index = command.getInteger(Command.KEY_INDEX) - 1; + int value = command.getInteger(Command.KEY_DATA); + return encodeOutputCommand(command.getDeviceId(), index, value); case Command.TYPE_ENGINE_STOP: - content.writeByte(0x01); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 1); case Command.TYPE_ENGINE_RESUME: - content.writeByte(0x00); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 0); case Command.TYPE_ALARM_GEOFENCE: content.writeShort(command.getInteger(Command.KEY_RADIUS)); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_MOVEMENT_ALARM, content); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 7439ea611..c6eba8fe1 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -19,11 +19,15 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeitrackProtocol extends BaseProtocol { - public MeitrackProtocol() { + @Inject + public MeitrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, @@ -32,18 +36,18 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO, Command.TYPE_SEND_SMS); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeitrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 5eab10498..343141dca 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ 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.model.Device; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; @@ -204,18 +204,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); - if (deviceModel == null) { - deviceModel = ""; + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); + if (model == null) { + model = ""; } - switch (deviceModel.toUpperCase()) { + switch (model.toUpperCase()) { case "MVT340": case "MVT380": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.0 * 2.0 / 1024.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0); break; case "MT90": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0)); break; case "T1": @@ -225,19 +225,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "MVT800": case "TC68": case "TC68S": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0); break; case "T311": case "T322X": case "T333": case "T355": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) / 100.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); - break; + case "T366": + case "T366G": default: - position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); + position.set(Position.KEY_BATTERY, parser.nextHexInt() / 100.0); + position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); break; } @@ -368,13 +367,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); - int checksum = 0; - for (int i = 0; i < command.length(); i += 1) { - checksum += command.charAt(i); - } - command.append(String.format("%02x", checksum & 0xff).toUpperCase()); + command.append(Checksum.sum(command.toString())); command.append("\r\n"); - channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data + channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); } return positions; @@ -404,7 +399,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x01: position.set(Position.KEY_EVENT, buf.readUnsignedByte()); @@ -418,12 +414,21 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x07: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; + case 0x14: + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + break; + case 0x15: + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + break; case 0x97: position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); break; case 0x9D: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); break; + case 0xFE69: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.readUnsignedByte(); break; @@ -432,7 +437,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x08: position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); @@ -446,6 +452,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x0B: position.setAltitude(buf.readShortLE()); break; + case 0x16: + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.01); + break; case 0x19: position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); break; @@ -482,7 +491,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x02: position.setLatitude(buf.readIntLE() * 0.000001); @@ -514,8 +524,30 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - buf.readUnsignedByte(); // id - buf.skipBytes(buf.readUnsignedByte()); // value + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + buf.readUnsignedByte(); // label + position.set(Position.PREFIX_TEMP + (id - 0x2A), buf.readShortLE() * 0.01); + break; + case 0xFE31: + buf.readUnsignedByte(); // alarm protocol + buf.readUnsignedByte(); // alarm type + buf.skipBytes(length - 2); + break; + default: + buf.skipBytes(length); + break; + } } positions.add(position); @@ -524,13 +556,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { return positions; } - private void requestPhotoPacket(Channel channel, SocketAddress socketAddress, String imei, String file, int index) { + private void requestPhotoPacket(Channel channel, SocketAddress remoteAddress, String imei, String file, int index) { if (channel != null) { String content = "D00," + file + "," + index; int length = 1 + imei.length() + 1 + content.length() + 5; String response = String.format("@@O%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -546,6 +578,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII); switch (type) { + case "AAC": + if (channel != null) { + String response = String.format("@@z27,%s,AAC,1*", imei); + response += Checksum.sum(response) + "\r\n"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + return null; case "D00": if (photo == null) { photo = Unpooled.buffer(); @@ -570,7 +609,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 354e81434..365dbb35a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Map; @@ -42,8 +43,8 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map<String, Object> attributes = command.getAttributes(); - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index 9fd9666e4..ccbc4db4c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -20,21 +20,25 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MictrackProtocol extends BaseProtocol { - public MictrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MictrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index 652ba3f6a..84ba75e7c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2020 Roeland Boeters (roeland@geodelta.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -114,14 +114,18 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeWifi(Network network, String data) { + private void decodeWifi(Network network, String data, boolean hasSsid) { String[] values = data.split(","); - for (int i = 0; i < values.length / 2; i++) { - network.addWifiAccessPoint(WifiAccessPoint.from(values[i * 2], Integer.parseInt(values[i * 2 + 1]))); + int step = hasSsid ? 3 : 2; + int offset = hasSsid ? 1 : 0; + for (int i = 0; i < values.length / step; i++) { + network.addWifiAccessPoint(WifiAccessPoint.from( + values[i * step + offset], Integer.parseInt(values[i * step + offset + 1]))); } } - private void decodeNetwork(Position position, String data, boolean hasWifi, boolean hasCell) throws ParseException { + private void decodeNetwork( + Position position, String data, boolean hasWifi, boolean hasSsid, boolean hasCell) throws ParseException { int index = 0; String[] values = data.split("\\+"); @@ -130,7 +134,7 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); if (hasWifi) { - decodeWifi(network, values[index++]); + decodeWifi(network, values[index++], hasSsid); } if (hasCell) { @@ -231,19 +235,22 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, fragments[4]); break; case "R1": - decodeNetwork(position, fragments[4], true, false); + decodeNetwork(position, fragments[4], true, false, false); break; case "R2": case "R3": - decodeNetwork(position, fragments[4], false, true); + decodeNetwork(position, fragments[4], false, false, true); break; case "R12": case "R13": - decodeNetwork(position, fragments[4], true, true); + decodeNetwork(position, fragments[4], true, false, true); break; case "RH": decodeStatus(position, fragments[4]); break; + case "Y1": + decodeNetwork(position, fragments[4], true, true, false); + break; default: return null; } diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index 822711603..59212e791 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MilesmateProtocol extends BaseProtocol { - public MilesmateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MilesmateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java index 901ceb8f7..21c629411 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 82534ecd8..44599accc 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,15 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MiniFinderProtocol extends BaseProtocol { - public MiniFinderProtocol() { + @Inject + public MiniFinderProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SET_TIMEZONE, Command.TYPE_VOICE_MONITORING, @@ -38,10 +42,10 @@ public class MiniFinderProtocol extends BaseProtocol { Command.TYPE_MODE_DEEP_SLEEP, Command.TYPE_SOS_NUMBER, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MiniFinderProtocolEncoder(MiniFinderProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index 2b7a960c4..f2e5eb905 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. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; @@ -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/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index f8801db74..5499a274e 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class Minifinder2Protocol extends BaseProtocol { - public Minifinder2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Minifinder2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); pipeline.addLast(new Minifinder2ProtocolDecoder(Minifinder2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 641a45864..0b08badb8 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -50,7 +50,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SERVICES = 0x03; public static final int MSG_RESPONSE = 0x7F; - private String decodeAlarm(int code) { + private String decodeAlarm(long code) { if (BitUtil.check(code, 0)) { return Position.ALARM_LOW_BATTERY; } @@ -181,7 +181,11 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); break; case 0x02: - position.set(Position.KEY_ALARM, decodeAlarm(buf.readIntLE())); + long alarm = buf.readUnsignedIntLE(); + position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + if (BitUtil.check(alarm, 31)) { + position.set("bark", true); + } break; case 0x14: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); @@ -194,7 +198,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); position.setCourse(buf.readUnsignedShortLE()); position.setAltitude(buf.readShortLE()); - position.setValid(buf.readUnsignedShortLE() > 0); + int hdop = buf.readUnsignedShortLE(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop * 0.1); position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; @@ -260,8 +266,16 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { hasLocation = true; break; case 0x30: - buf.readUnsignedInt(); // timestamp - position.set(Position.KEY_STEPS, buf.readUnsignedInt()); + buf.readUnsignedIntLE(); // timestamp + position.set(Position.KEY_STEPS, buf.readUnsignedIntLE()); + break; + case 0x31: + int i = 1; + while (buf.readerIndex() < endIndex) { + position.set("activity" + i + "Time", buf.readUnsignedIntLE()); + position.set("activity" + i, buf.readUnsignedIntLE()); + i += 1; + } break; case 0x40: buf.readUnsignedIntLE(); // timestamp diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 28380a2af..1b06c2249 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MobilogixProtocol extends BaseProtocol { - public MobilogixProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MobilogixProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index f3b70e40c..d7600ecbb 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -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())); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 7b554266f..16438e122 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MoovboxProtocol extends BaseProtocol { - public MoovboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MoovboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java index 3116d073c..8e6679b05 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; import org.w3c.dom.Document; diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index 680687e15..3101c9b75 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MotorProtocol extends BaseProtocol { - public MotorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MotorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MotorProtocolDecoder(MotorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java index 8ce4fe8b1..9bca4d9bc 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 14a66ce5c..019fe4fa9 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -19,22 +19,25 @@ import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; + public class Mta6Protocol extends BaseProtocol { - public Mta6Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Mta6Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new Mta6ProtocolDecoder( - Mta6Protocol.this, !Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); + Mta6Protocol.this, !config.getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); } }); } diff --git a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java index 88419b871..896c7a2d2 100644 --- a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java @@ -26,7 +26,7 @@ import io.netty.handler.codec.http.HttpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index 44372ce83..e085b6221 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MtxProtocol extends BaseProtocol { - public MtxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MtxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java index d1207bedf..e94d12b36 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index dbe43fe45..1190bf527 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class MxtProtocol extends BaseProtocol { - public MxtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MxtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MxtFrameDecoder()); pipeline.addLast(new MxtProtocolDecoder(MxtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index 379b610e1..b3e2295e8 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index 2c946c39f..46a6c33a5 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NavigilProtocol extends BaseProtocol { - public NavigilProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavigilProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavigilFrameDecoder()); pipeline.addLast(new NavigilProtocolDecoder(NavigilProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java index db5521201..6dadbc559 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index d5af6838d..640a77803 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NavisProtocol extends BaseProtocol { - public NavisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisFrameDecoder()); pipeline.addLast(new NavisProtocolDecoder(NavisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 7ba474ae0..77158b315 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,11 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; -import org.traccar.helper.Checksum.Algorithm; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -591,10 +590,8 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { private void sendFlexReply(Channel channel, ByteBuf data) { if (channel != null) { - ByteBuf cs = Unpooled.buffer(1); - cs.writeByte(Checksum.crc8(new Algorithm(8, 0x31, 0xFF, false, false, 0x00), data.nioBuffer())); - - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(data, cs), channel.remoteAddress())); + data.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, data.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(data, channel.remoteAddress())); } } diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 78755ea4d..388f141f8 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NavisetProtocol extends BaseProtocol { - public NavisetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisetFrameDecoder()); pipeline.addLast(new NavisetProtocolDecoder(NavisetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java index 10d71d76c..47d10b310 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java index 0fb82528b..2ab7d11a9 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,12 @@ public class NavtelecomFrameDecoder extends BaseFrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - if (buf.getByte(buf.readerIndex()) == '@') { + if (buf.getByte(buf.readerIndex()) == 0x7f) { + + buf.skipBytes(1); + return null; + + } else if (buf.getByte(buf.readerIndex()) == '@') { int length = buf.getUnsignedShortLE(12) + 12 + 2 + 2; if (buf.readableBytes() >= length) { diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 29ce8c41e..50013d1a4 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NavtelecomProtocol extends BaseProtocol { - public NavtelecomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavtelecomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavtelecomFrameDecoder()); pipeline.addLast(new NavtelecomProtocolDecoder(NavtelecomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index bdcc12c4c..08b1a8d0f 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -195,6 +195,9 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { + + int value; + switch (j + 1) { case 1: position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); @@ -205,8 +208,12 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 3: position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); break; + case 8: + value = buf.readUnsignedByte(); + position.setValid(BitUtil.check(value, 1)); + position.set(Position.KEY_SATELLITES, BitUtil.from(value, 2)); + break; case 9: - position.setValid(true); position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); break; case 10: @@ -221,6 +228,83 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 13: position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); break; + case 14: + position.setCourse(buf.readUnsignedShortLE()); + break; + case 15: + position.set(Position.KEY_ODOMETER, buf.readFloatLE()); + break; + case 19: + position.set(Position.KEY_POWER, buf.readShortLE() * 0.001); + break; + case 20: + position.set(Position.KEY_BATTERY, buf.readShortLE() * 0.001); + break; + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + position.set(Position.PREFIX_ADC + (j + 2 - 21), buf.readUnsignedShortLE() * 0.001); + break; + case 29: + value = buf.readUnsignedByte(); + for (int k = 0; k <= 7; k++) { + position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(value, k)); + } + break; + case 31: + value = buf.readUnsignedByte(); + for (int k = 0; k <= 3; k++) { + position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(value, k)); + } + break; + case 33: + case 34: + position.set(Position.PREFIX_COUNT + (j + 2 - 33), buf.readUnsignedIntLE()); + break; + case 35: + case 36: + position.set("freq" + (j + 2 - 35), buf.readUnsignedShortLE()); + break; + case 37: + position.set(Position.KEY_HOURS, buf.readUnsignedIntLE()); + break; + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + value = buf.readUnsignedShortLE(); + position.set("fuel" + (j + 2 - 38), (value < 65500) ? value : null); + break; + case 44: + value = buf.readUnsignedShortLE(); + position.set(Position.KEY_FUEL_LEVEL, (value < 65500) ? value : null); + break; + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 51: + case 52: + value = buf.readByte(); + position.set( + Position.PREFIX_TEMP + (j + 2 - 45), + (value != (byte) 0x80) ? value : null); + break; + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + position.set("fuelTemp" + (j + 2 - 78), (int) buf.readByte()); + break; default: buf.skipBytes(getItemLength(j + 1)); break; @@ -235,12 +319,11 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { 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); + response.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, response.nioBuffer())); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } diff --git a/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java new file mode 100644 index 000000000..5b610013a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class NdtpV6FrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + return buf; + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6Protocol.java b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java new file mode 100644 index 000000000..ce0dbbef2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class NdtpV6Protocol extends BaseProtocol { + + @Inject + public NdtpV6Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new NdtpV6ProtocolDecoder(NdtpV6Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java new file mode 100644 index 000000000..35cb0bae8 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java @@ -0,0 +1,203 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.Date; + +public class NdtpV6ProtocolDecoder extends BaseProtocolDecoder { + + public NdtpV6ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final byte[] SIGNATURE = {0x7E, 0x7E}; + + private static final int NPL_FLAG_CRC = 2; + private static final int NPH_RESULT_OK = 0x00000000; + private static final int NPL_TYPE_NPH = 2; + private static final int NPL_ADDRESS_SERVER = 0; + + private static final int NPH_RESULT = 0; + + private static final int NPH_SRV_GENERIC_CONTROLS = 0; + private static final int NPH_SRV_NAVDATA = 1; + + private static final int NPH_SGC_RESULT = NPH_RESULT; + private static final int NPH_SGC_CONN_REQUEST = 100; + + private static final int NPH_SND_RESULT = NPH_RESULT; + + private void sendResponse( + Channel channel, int serviceId, long requestId) { + + ByteBuf content = Unpooled.buffer(); + content.writeShortLE(serviceId); + content.writeIntLE(NPH_SND_RESULT); + content.writeIntLE((int) requestId); + content.writeIntLE(NPH_RESULT_OK); + + ByteBuf response = Unpooled.buffer(); + response.writeBytes(SIGNATURE); + response.writeShortLE(content.readableBytes()); + response.writeShortLE(NPL_FLAG_CRC); // flags + response.writeShort(Checksum.crc16(Checksum.CRC16_MODBUS, content.nioBuffer())); + response.writeByte(NPL_TYPE_NPH); // type + response.writeIntLE(NPL_ADDRESS_SERVER); // peer address + response.writeShortLE(0); // request id + response.writeBytes(content); + content.release(); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + + private static final short MAIN_NAV_DATA = 0; + private static final short ADDITIONAL_NAV_DATA = 2; + + private void decodeData(ByteBuf buf, Position position) { + + short itemType; + short itemIndex; + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == MAIN_NAV_DATA && (itemIndex == 0 || itemIndex == 1)) { + + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLongitude(buf.readIntLE() / 10000000.0); + position.setLatitude(buf.readIntLE() / 10000000.0); + + short flags = buf.readUnsignedByte(); + position.setValid(BitUtil.check(flags, 7)); + if (BitUtil.check(flags, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 20); + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedShortLE()); + position.setAltitude(buf.readShortLE()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_PDOP, buf.readUnsignedByte()); + } + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == ADDITIONAL_NAV_DATA && itemIndex == 0) { + + position.set(Position.KEY_BATTERY_LEVEL, Math.max((buf.readUnsignedShortLE() - 3600) / 6, 100)); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE()); + + buf.readUnsignedByte(); // inputs + buf.readUnsignedByte(); // outputs + buf.readUnsignedShortLE(); // in1 count + buf.readUnsignedShortLE(); // in2 count + buf.readUnsignedShortLE(); // in3 count + buf.readUnsignedShortLE(); // in4 count + buf.readUnsignedIntLE(); // track length + + position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); + position.set(Position.KEY_GPS, buf.readUnsignedByte()); + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + + buf.skipBytes(2); // signature + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // connection flags + buf.readUnsignedShortLE(); // checksum + buf.readUnsignedByte(); // type + buf.readUnsignedIntLE(); // address + buf.readUnsignedShortLE(); // identification + + int serviceId = buf.readUnsignedShortLE(); + int serviceType = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // request flags + long requestId = buf.readUnsignedIntLE(); + + if (deviceSession == null && serviceId == NPH_SRV_GENERIC_CONTROLS && serviceType == NPH_SGC_CONN_REQUEST) { + + buf.readUnsignedShortLE(); // version major + buf.readUnsignedShortLE(); // version minor + buf.readUnsignedShortLE(); // connection flags + + int deviceId = buf.readUnsignedShortLE(); + Position position = new Position(getProtocolName()); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResponse(channel, serviceId, requestId); + } + + position.set(Position.KEY_RESULT, String.valueOf(NPH_SGC_RESULT)); + position.setTime(new Date()); + getLastLocation(position, new Date()); + position.setValid(false); + + return position; + + } + + if (serviceId == NPH_SRV_NAVDATA) { + + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResponse(channel, serviceId, requestId); + } + + decodeData(buf, position); + + return position; + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java new file mode 100644 index 000000000..7aac8658a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java @@ -0,0 +1,42 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class NdtpV6ProtocolEncoder extends BaseProtocolEncoder { + + public NdtpV6ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_IDENTIFICATION: + return "BB+IDNT"; + case Command.TYPE_REBOOT_DEVICE: + return "BB+RESET"; + case Command.TYPE_POSITION_SINGLE: + return "BB+RRCD"; + default: + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index e545a9969..0787b6562 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NeosProtocol extends BaseProtocol { - public NeosProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public NeosProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new NeosProtocolDecoder(NeosProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java index 6b5596dba..18ebc49da 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index c114d19fc..f27e4afb8 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NetProtocol extends BaseProtocol { - public NetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java index c71a792a2..ebffb06f1 100644 --- a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index b57b18a3a..0fbe0c689 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NiotProtocol extends BaseProtocol { - public NiotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NiotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new NiotProtocolDecoder(NiotProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 47c6e2ffd..35614ccca 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -20,7 +20,8 @@ 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.helper.BufferUtil; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -57,12 +58,6 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { } } - private double readCoordinate(ByteBuf buf) { - long value = buf.readUnsignedInt(); - double result = BitUtil.to(value, 31) / 1800000.0; - return BitUtil.check(value, 31) ? -result : result; - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -96,8 +91,8 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { .setSecond(BcdUtil.readInteger(buf, 2)); position.setTime(dateBuilder.getDate()); - position.setLatitude(readCoordinate(buf)); - position.setLongitude(readCoordinate(buf)); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); BcdUtil.readInteger(buf, 4); // reserved position.setCourse(BcdUtil.readInteger(buf, 4)); diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index 3df364c30..626991029 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -18,20 +18,24 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class NoranProtocol extends BaseProtocol { - public NoranProtocol() { + @Inject + public NoranProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java index 53dae7fd6..53b58f9b6 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index d319b22f3..7ed488e38 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class NvsProtocol extends BaseProtocol { - public NvsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NvsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NvsFrameDecoder()); pipeline.addLast(new NvsProtocolDecoder(NvsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java index 5d1159f7d..f826c4121 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index 58974be5c..e7ef10945 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class NyitechProtocol extends BaseProtocol { - public NyitechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NyitechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new NyitechProtocolDecoder(NyitechProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java index 62b41a2ea..49bc5b824 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index 10a55759b..94f450426 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ObdDongleProtocol extends BaseProtocol { - public ObdDongleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ObdDongleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); pipeline.addLast(new ObdDongleProtocolDecoder(ObdDongleProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java index 1c9771ce9..bf0ba6f82 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 5056f68aa..0539bada6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OigoProtocol extends BaseProtocol { - public OigoProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public OigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java index b9cc71e8c..b0c7c3bc6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 9571ccc48..29c8bc1b9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -20,13 +20,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OkoProtocol extends BaseProtocol { - public OkoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OkoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new OkoProtocolDecoder(OkoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java index fa35ab455..3bb62acb9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index 96660cb59..dd400c779 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OmnicommProtocol extends BaseProtocol { - public OmnicommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OmnicommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OmnicommFrameDecoder()); pipeline.addLast(new OmnicommProtocolDecoder(OmnicommProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java index f90d1f2b3..9d747032b 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 5ef3260c6..5443b4ffc 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OpenGtsProtocol extends BaseProtocol { - public OpenGtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OpenGtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java index b76cbfa85..255a81ae6 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java new file mode 100644 index 000000000..fb09f0abb --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestEncoder; +import io.netty.handler.codec.http.HttpResponseDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerClient; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class OrbcommProtocol extends BaseProtocol { + + @Inject + public OrbcommProtocol(Config config) { + addClient(new TrackerClient(config, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new HttpRequestEncoder()); + pipeline.addLast(new HttpResponseDecoder()); + pipeline.addLast(new HttpObjectAggregator(65535)); + pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, config)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java new file mode 100644 index 000000000..1164d72a1 --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -0,0 +1,124 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpResponse; +import org.traccar.BasePipelineFactory; +import org.traccar.BaseProtocolDecoder; +import org.traccar.session.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonValue; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedList; +import java.util.TimeZone; + +public class OrbcommProtocolDecoder extends BaseProtocolDecoder { + + public OrbcommProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpResponse response = (FullHttpResponse) msg; + String content = response.content().toString(StandardCharsets.UTF_8); + JsonObject json = Json.createReader(new StringReader(content)).readObject(); + + if (channel != null && !json.getString("NextStartUTC").isEmpty()) { + OrbcommProtocolPoller poller = + BasePipelineFactory.getHandler(channel.pipeline(), OrbcommProtocolPoller.class); + if (poller != null) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + poller.setStartTime(dateFormat.parse(json.getString("NextStartUTC"))); + } + } + + if (json.get("Messages").getValueType() == JsonValue.ValueType.NULL) { + return null; + } + + LinkedList<Position> positions = new LinkedList<>(); + + JsonArray messages = json.getJsonArray("Messages"); + for (int i = 0; i < messages.size(); i++) { + JsonObject message = messages.getJsonObject(i); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, message.getString("MobileID")); + if (deviceSession != null) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setDeviceTime(dateFormat.parse(message.getString("MessageUTC"))); + + JsonArray fields = message.getJsonObject("Payload").getJsonArray("Fields"); + for (int j = 0; j < fields.size(); j++) { + JsonObject field = fields.getJsonObject(j); + String value = field.getString("Value"); + switch (field.getString("Name").toLowerCase()) { + case "eventtime": + position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + break; + case "latitude": + position.setLatitude(Integer.parseInt(value) / 60000.0); + break; + case "longitude": + position.setLongitude(Integer.parseInt(value) / 60000.0); + break; + case "speed": + position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); + break; + case "heading": + int heading = Integer.parseInt(value); + position.setCourse(heading <= 360 ? heading : 0); + break; + default: + break; + } + } + + if (position.getLatitude() != 0 && position.getLongitude() != 0) { + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + } else { + getLastLocation(position, position.getDeviceTime()); + } + + positions.add(position); + + } + } + + return positions.isEmpty() ? null : positions; + } + +} diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java new file mode 100644 index 000000000..0f57bfb49 --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -0,0 +1,74 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringEncoder; +import org.traccar.BaseProtocolPoller; +import org.traccar.Protocol; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class OrbcommProtocolPoller extends BaseProtocolPoller { + + private final String accessId; + private final String password; + private final String host; + + private Date startTime = new Date(); + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public OrbcommProtocolPoller(Protocol protocol, Config config) { + super(config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); + accessId = config.getString(Keys.ORBCOMM_ACCESS_ID); + password = config.getString(Keys.ORBCOMM_PASSWORD); + host = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); + } + + @Override + protected void sendRequest(Channel channel, SocketAddress remoteAddress) { + + QueryStringEncoder encoder = new QueryStringEncoder("/GLGW/2/RestMessages.svc/JSON/get_return_messages/"); + encoder.addParam("access_id", accessId); + encoder.addParam("password", password); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + encoder.addParam("start_utc", dateFormat.format(startTime)); + + HttpRequest request = new DefaultFullHttpRequest( + HttpVersion.HTTP_1_1, HttpMethod.GET, encoder.toString(), Unpooled.buffer()); + request.headers().add(HttpHeaderNames.HOST, host); + request.headers().add(HttpHeaderNames.CONTENT_LENGTH, 0); + channel.writeAndFlush(request); + } + +} diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index 8485ae638..2dec7cd06 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OrionProtocol extends BaseProtocol { - public OrionProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OrionProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OrionFrameDecoder()); pipeline.addLast(new OrionProtocolDecoder(OrionProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java index af819989e..681891edb 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index d3aa2fd6f..a86bc70d7 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OsmAndProtocol extends BaseProtocol { - public OsmAndProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OsmAndProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index ec9bbc240..c8968023a 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,8 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; -import org.traccar.database.CommandsManager; import org.traccar.helper.DateUtil; import org.traccar.model.CellTower; import org.traccar.model.Command; @@ -61,6 +59,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setValid(true); Network network = new Network(); + Double latitude = null; + Double longitude = null; for (Map.Entry<String, List<String>> entry : params.entrySet()) { for (String value : entry.getValue()) { @@ -94,15 +94,15 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { } break; case "lat": - position.setLatitude(Double.parseDouble(value)); + latitude = Double.parseDouble(value); break; case "lon": - position.setLongitude(Double.parseDouble(value)); + longitude = Double.parseDouble(value); break; case "location": String[] location = value.split(","); - position.setLatitude(Double.parseDouble(location[0])); - position.setLongitude(Double.parseDouble(location[1])); + latitude = Double.parseDouble(location[0]); + longitude = Double.parseDouble(location[1]); break; case "cell": String[] cell = value.split(","); @@ -143,6 +143,9 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { case "driverUniqueId": position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; + case "charge": + position.set(Position.KEY_CHARGE, Boolean.parseBoolean(value)); + break; default: try { position.set(entry.getKey(), Double.parseDouble(value)); @@ -172,17 +175,17 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setNetwork(network); } - if (position.getLatitude() == 0 && position.getLongitude() == 0) { + if (latitude != null && longitude != null) { + position.setLatitude(latitude); + position.setLongitude(longitude); + } else { getLastLocation(position, position.getDeviceTime()); } if (position.getDeviceId() != 0) { String response = null; - CommandsManager commandsManager = Context.getCommandsManager(); - if (commandsManager != null) { - for (Command command : commandsManager.readQueuedCommands(position.getDeviceId(), 1)) { - response = command.getString(Command.KEY_DATA); - } + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); } if (response != null) { sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index c728a404d..0099be456 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OutsafeProtocol extends BaseProtocol { - public OutsafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OutsafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java index 9de77d241..62b873be7 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index 0086371d8..9ad337f19 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -22,13 +22,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class OwnTracksProtocol extends BaseProtocol { - public OwnTracksProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OwnTracksProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java index 509d14ae4..71ac87168 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index 08991ab64..709729ef1 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PacificTrackProtocol extends BaseProtocol { - public PacificTrackProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public PacificTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java index b5d34a029..7079745be 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index 6b5d75c5e..1d13eea95 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PathAwayProtocol extends BaseProtocol { - public PathAwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PathAwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java index 02a15e34a..3e7fa9a5b 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java @@ -24,7 +24,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index d88c1ab72..aa45a0def 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PiligrimProtocol extends BaseProtocol { - public PiligrimProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PiligrimProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 26ce2fe53..34c879cb8 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,16 +22,19 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; +import java.util.regex.Pattern; public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { @@ -47,6 +50,21 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { public static final int MSG_GPS_SENSORS = 0xF2; public static final int MSG_EVENTS = 0xF3; + private static final Pattern PATTERN = new PatternBuilder() + .expression("[^$]+") + .text("$GPRMC,") + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .expression("([AV]),") // validity + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(d{2,3})(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("(dd)(dd)(dd),") // date (ddmmyy) + .any() + .compile(); + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -150,6 +168,42 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } return positions; + + } else if (uri.startsWith("/push.do")) { + + sendResponse(channel, "PUSH.DO: OK"); + + String sentence = request.content().toString(StandardCharsets.US_ASCII); + + String[] parts = sentence.split("&"); + String phone = parts[1].substring(16); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone); + if (deviceSession == null) { + return null; + } + + Parser parser = new Parser(PATTERN, parts[2]); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + return position; + } return null; diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index d5f28da9d..b2101b18d 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PluginProtocol extends BaseProtocol { - public PluginProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PluginProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java index 65de211ac..6ee95d18a 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index a3e548716..69666cc0e 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PolteProtocol extends BaseProtocol { - public PolteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PolteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java index ce45abef6..028de5424 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index b7faae08a..de78013fa 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -21,17 +21,21 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PortmanProtocol extends BaseProtocol { - public PortmanProtocol() { + @Inject + public PortmanProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java index e1847a2b2..da9403313 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index 9d35c1c2f..b77dd97bf 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -21,17 +21,21 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PretraceProtocol extends BaseProtocol { - public PretraceProtocol() { + @Inject + public PretraceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java index a19384e62..ff6ad763a 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 1083a252e..a109e7a07 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -16,10 +16,9 @@ package org.traccar.protocol; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; public class PretraceProtocolEncoder extends BaseProtocolEncoder { @@ -35,7 +34,7 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - String uniqueId = Context.getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + String uniqueId = getUniqueId(command.getDeviceId()); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index 6821cd949..f5e904541 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -19,20 +19,24 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class PricolProtocol extends BaseProtocol { - public PricolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PricolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(64)); pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java index 190c68258..5f6805f09 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index aac84205d..49eb6847f 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ProgressProtocol extends BaseProtocol { - public ProgressProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ProgressProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ProgressProtocolDecoder(ProgressProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java index 0025cd9e7..e3a5881da 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index d8c7008cb..73f978cbd 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -18,24 +18,28 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PstProtocol extends BaseProtocol { - public PstProtocol() { + @Inject + public PstProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); pipeline.addLast(new PstProtocolDecoder(PstProtocol.this)); } }); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstFrameEncoder()); pipeline.addLast(new PstFrameDecoder()); pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java index e3fe1af62..872e77a3a 100644 --- a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index 09bd9b121..b272582a4 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Pt215Protocol extends BaseProtocol { - public Pt215Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt215Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 1, -1, 0)); pipeline.addLast(new Pt215ProtocolDecoder(Pt215Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java index 48ce7dede..f669c5ffd 100644 --- a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index 1ad0026a3..d72774f47 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Pt3000Protocol extends BaseProtocol { - public Pt3000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt3000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java index e7f9e062a..c33660f51 100644 --- a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 56444fb42..d5d30e8e8 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -19,20 +19,24 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Pt502Protocol extends BaseProtocol { - public Pt502Protocol() { + @Inject + public Pt502Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_SET_TIMEZONE, Command.TYPE_ALARM_SPEED, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Pt502FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Pt502ProtocolEncoder(Pt502Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index ff92b51f1..2a6a81a65 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -20,8 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -175,14 +174,13 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index c502426c5..58345f025 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Pt60Protocol extends BaseProtocol { - public Pt60Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt60Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java index 6a3fe2734..94b549fe6 100644 --- a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index 3726233b4..a406f6306 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class R12wProtocol extends BaseProtocol { - public R12wProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public R12wProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java index d60318447..3be784911 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index c9db10610..63ca3476c 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RaceDynamicsProtocol extends BaseProtocol { - public RaceDynamicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaceDynamicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1500)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java index f441bf8ed..89639ad30 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 9783778f0..9d88c6d72 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RadarProtocol extends BaseProtocol { - public RadarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RadarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 12, 2, -14, 0)); pipeline.addLast(new RadarProtocolDecoder(RadarProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java index d87f77b84..818e97f8b 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index 44faadb3b..db70396ee 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RaveonProtocol extends BaseProtocol { - public RaveonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaveonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java index 50acd20a1..dfc21bf69 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 0bc9870bc..0d50db01e 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RecodaProtocol extends BaseProtocol { - public RecodaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RecodaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); pipeline.addLast(new RecodaProtocolDecoder(RecodaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java index 04098225f..0c417a62f 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index fae81f7d2..1d4b419bb 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RetranslatorProtocol extends BaseProtocol { - public RetranslatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RetranslatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RetranslatorFrameDecoder()); pipeline.addLast(new RetranslatorProtocolDecoder(RetranslatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java index 5bf6cef50..afbf7e511 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocol.java b/src/main/java/org/traccar/protocol/RfTrackProtocol.java new file mode 100644 index 000000000..d3b41e93e --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class RfTrackProtocol extends BaseProtocol { + + @Inject + public RfTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(16384)); + pipeline.addLast(new RfTrackProtocolDecoder(RfTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java new file mode 100644 index 000000000..28a3ac29c --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -0,0 +1,163 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.model.CellTower; +import org.traccar.model.Command; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; +import org.traccar.session.DeviceSession; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { + + public RfTrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder( + request.content().toString(StandardCharsets.US_ASCII), false); + Map<String, List<String>> params = decoder.parameters(); + + Position position = new Position(getProtocolName()); + Network network = new Network(); + + for (Map.Entry<String, List<String>> entry : params.entrySet()) { + for (String value : entry.getValue()) { + switch (entry.getKey()) { + case "i": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + break; + case "v": + position.set(Position.KEY_VERSION_FW, value); + break; + case "t": + position.setDeviceTime(new Date(Long.parseLong(value))); + break; + case "bat": + int battery = Integer.parseInt(value); + position.set(Position.KEY_BATTERY_LEVEL, battery & 0xff); + position.set("plugStatus", (battery >> 8) & 0x0f); + position.set(Position.KEY_CHARGE, ((battery >> 12) & 0x0f) == 1); + break; + case "id": + position.set("braceletId", value); + break; + case "rc": + int braceletCode = Integer.parseInt(value); + position.set("braceletCode", braceletCode & 0xffff); + position.set("braceletStatus", braceletCode >> 16); + break; + case "idt": + long braceletTime = Long.parseLong(value); + position.set("lastHeartbeat", (braceletTime >> 45) * 10); + position.set("lastPaired", ((braceletTime >> 30) & 0xffff) * 10); + position.set("lastUnpaired", ((braceletTime >> 15) & 0xffff) * 10); + break; + case "mt": + int vibrationTime = Integer.parseInt(value); + position.set("vibrationDevice", (vibrationTime & 0x7fff) * 10); + position.set("vibrationBracelet", (vibrationTime >> 15) * 10); + break; + case "gps": + JsonObject location = Json.createReader(new StringReader(value)).readObject(); + position.setValid(true); + position.setAccuracy(location.getJsonNumber("a").doubleValue()); + position.setLongitude(location.getJsonNumber("x").doubleValue()); + position.setLatitude(location.getJsonNumber("y").doubleValue()); + position.setAltitude(location.getJsonNumber("z").doubleValue()); + position.setFixTime(new Date(location.getJsonNumber("t").longValue())); + break; + case "gsm": + JsonObject cellInfo = Json.createReader(new StringReader(value)).readObject(); + int mcc = cellInfo.getInt("c"); + int mnc = cellInfo.getInt("n"); + JsonArray cells = cellInfo.getJsonArray("b"); + for (int i = 0; i < cells.size(); i++) { + JsonObject cell = cells.getJsonObject(i); + network.addCellTower(CellTower.from( + mcc, mnc, cell.getInt("l"), cell.getInt("c"), cell.getInt("b"))); + } + break; + case "dbm": + position.set(Position.KEY_RSSI, Integer.parseInt(value)); + break; + case "bar": + position.set("pressure", Double.parseDouble(value)); + break; + case "cob": + position.set("pressureChanges", value); + break; + case "wifi": + JsonArray wifiInfo = Json.createReader(new StringReader(value)).readArray(); + for (int i = 0; i < wifiInfo.size(); i++) { + JsonObject wifi = wifiInfo.getJsonObject(i); + network.addWifiAccessPoint(WifiAccessPoint.from( + wifi.getString("m").replace('-', ':'), wifi.getInt("l"))); + } + break; + case "u_ids": + position.set("unpairedIds", value); + break; + default: + break; + } + } + } + + if (position.getFixTime() == null) { + getLastLocation(position, position.getDeviceTime()); + } + + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + + String response = "{}"; + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); + } + sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index de1026672..9b9c00cb2 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -19,14 +19,18 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RitiProtocol extends BaseProtocol { - public RitiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RitiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); pipeline.addLast(new RitiProtocolDecoder(RitiProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java index 46267ca90..501d5faa7 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index c2c531293..ab2bc5842 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RoboTrackProtocol extends BaseProtocol { - public RoboTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RoboTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RoboTrackFrameDecoder()); pipeline.addLast(new RoboTrackProtocolDecoder(RoboTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java index b613f31d7..ffe16bd7b 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 10d11d493..109d91b16 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class RstProtocol extends BaseProtocol { - public RstProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public RstProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new RstProtocolDecoder(RstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java index 9e3261a04..fcc96fbf1 100644 --- a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 5d1f86553..99a9686f6 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -19,11 +19,15 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class RuptelaProtocol extends BaseProtocol { - public RuptelaProtocol() { + @Inject + public RuptelaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, @@ -35,9 +39,9 @@ public class RuptelaProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL, Command.TYPE_SET_CONNECTION, Command.TYPE_SET_ODOMETER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); pipeline.addLast(new RuptelaProtocolEncoder(RuptelaProtocol.this)); pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5c2885a8b..77df0deb7 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -50,6 +49,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SMS_VIA_GPRS_RESPONSE = 7; public static final int MSG_SMS_VIA_GPRS = 8; public static final int MSG_DTCS = 9; + public static final int MSG_IDENTIFICATION = 15; public static final int MSG_SET_IO = 17; public static final int MSG_FILES = 37; public static final int MSG_EXTENDED_RECORDS = 68; @@ -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; @@ -294,7 +297,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; @@ -303,6 +306,18 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { return null; + } else if (type == MSG_IDENTIFICATION) { + + ByteBuf content = Unpooled.buffer(); + content.writeByte(1); + ByteBuf response = RuptelaProtocolEncoder.encodeContent(type, content); + content.release(); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + return null; + } else { return decodeCommandResponse(deviceSession, type, buf); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java index 442961b19..5ec971a98 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -80,14 +80,14 @@ public class RuptelaProtocolEncoder extends BaseProtocolEncoder { return encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); case Command.TYPE_OUTPUT_CONTROL: content.writeInt(command.getInteger(Command.KEY_INDEX)); - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); case Command.TYPE_SET_CONNECTION: String c = command.getString(Command.KEY_SERVER) + "," + command.getInteger(Command.KEY_PORT) + ",TCP"; content.writeBytes(c.getBytes(StandardCharsets.US_ASCII)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); case Command.TYPE_SET_ODOMETER: - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); default: return null; diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index e78664c40..f904ed9ff 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class S168Protocol extends BaseProtocol { - public S168Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public S168Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 71aff1a65..cf665c6ba 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,13 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.text.DateFormat; @@ -48,9 +51,14 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + Network network = new Network(); + String content = values[4]; String[] fragments = content.split(";"); for (String fragment : fragments) { + if (fragment.isEmpty()) { + continue; + } int dataIndex = fragment.indexOf(':'); String type = fragment.substring(0, dataIndex); @@ -70,12 +78,44 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { position.setCourse(Integer.parseInt(values[index++])); position.setAltitude(Integer.parseInt(values[index++])); break; + case "CELL": + int cellCount = Integer.parseInt(values[index++]); + int mcc = Integer.parseInt(values[index++], 16); + int mnc = Integer.parseInt(values[index++], 16); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, Integer.parseInt(values[index++], 16), Integer.parseInt(values[index++], 16), + Integer.parseInt(values[index++], 16))); + } + break; + case "WIFI": + int wifiCount = Integer.parseInt(values[index++]); + for (int i = 0; i < wifiCount; i++) { + network.addWifiAccessPoint(WifiAccessPoint.from( + values[index++].replace('-', ':'), Integer.parseInt(values[index++]))); + } + break; + case "STATUS": + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); + position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); + break; default: break; } } - return position.getAttributes().containsKey(Position.KEY_SATELLITES) ? position : null; + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + if (!position.hasAttribute(Position.KEY_SATELLITES)) { + getLastLocation(position, null); + } + + if (position.getNetwork() != null || !position.getAttributes().isEmpty()) { + return position; + } else { + return null; + } } } diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 0ec847b60..403243cdc 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SabertekProtocol extends BaseProtocol { - public SabertekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SabertekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SabertekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SabertekProtocolDecoder(SabertekProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java index 3033aa2cc..71279812c 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index 6799c57e6..1a0e7b0e9 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -20,21 +20,25 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SanavProtocol extends BaseProtocol { - public SanavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java index 7e1c158e6..6741cb67c 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index 3104e9366..ea44bf868 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SanulProtocol extends BaseProtocol { - public SanulProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanulProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new SanulProtocolDecoder(SanulProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java index 036d1ee51..9568cd6d3 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index b69fdd1fe..d90033e38 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SatsolProtocol extends BaseProtocol { - public SatsolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SatsolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); pipeline.addLast(new SatsolProtocolDecoder(SatsolProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java index c457d5620..37a84be04 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index e2f2cbe1f..9a268af62 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SigfoxProtocol extends BaseProtocol { - public SigfoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SigfoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index ce577f392..4ed2bb51d 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,7 +22,8 @@ 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.helper.BufferUtil; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DataConverter; @@ -159,18 +160,8 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { if (event == 0x0f || event == 0x1f) { position.setValid(event >> 4 > 0); - - long value; - value = buf.readUnsignedInt(); - position.setLatitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLatitude(-position.getLatitude()); - } - value = buf.readUnsignedInt(); - position.setLongitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLongitude(-position.getLongitude()); - } + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); position.set(Position.KEY_BATTERY, (int) buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index 8963721c8..f12958a50 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SiwiProtocol extends BaseProtocol { - public SiwiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SiwiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SiwiProtocolDecoder(SiwiProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java index bf8bfab77..7ba501834 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 7c6203d86..7ae26f634 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SkypatrolProtocol extends BaseProtocol { - public SkypatrolProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SkypatrolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java index 8aae310bb..6ffcbbe44 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -20,8 +20,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.BitUtil; @@ -35,11 +34,15 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder { private static final Logger LOGGER = LoggerFactory.getLogger(SkypatrolProtocolDecoder.class); - private final long defaultMask; + private long defaultMask; public SkypatrolProtocolDecoder(Protocol protocol) { super(protocol); - defaultMask = Context.getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + defaultMask = getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); } private static double convertCoordinate(long coordinate) { diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index bcf43f68b..cb7efb7ee 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SmartSoleProtocol extends BaseProtocol { - public SmartSoleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SmartSoleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java index 04920c969..7fc38f061 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index 482c8347c..22b343537 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SmokeyProtocol extends BaseProtocol { - public SmokeyProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SmokeyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java index 9da52e97a..2244ad289 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 53a948cdc..0676aa629 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SolarPoweredProtocol extends BaseProtocol { - public SolarPoweredProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SolarPoweredProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new SolarPoweredProtocolDecoder(SolarPoweredProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java index 9d5dc072f..0432fbd03 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index bbf0e8d8a..6bd802fed 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SpotProtocol extends BaseProtocol { - public SpotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SpotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java index 34417d95f..d493b748d 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index 5630722ee..d578fa705 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class StarLinkProtocol extends BaseProtocol { - public StarLinkProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StarLinkProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 7a6b6f4fe..aa23bfac5 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,9 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; @@ -55,17 +56,21 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { public StarLinkProtocolDecoder(Protocol protocol) { super(protocol); + } - setFormat(Context.getConfig().getString( + @Override + protected void init() { + setFormat(getConfig().getString( getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#")); - setDateFormat(Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); + setDateFormat(getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); } public String[] getFormat(long deviceId) { - return Context.getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".format", format, false, false).split(","); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), deviceId); + return (value != null ? value : format).split(","); } public void setFormat(String format) { @@ -73,8 +78,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public DateFormat getDateFormat(long deviceId) { - DateFormat dateFormat = new SimpleDateFormat(Context.getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".dateFormat", this.dateFormat, false, false)); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_DATE_FORMAT.withPrefix(getProtocolName()), deviceId); + DateFormat dateFormat = new SimpleDateFormat(value != null ? value : this.dateFormat); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat; } @@ -313,7 +319,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } if (lac != null && cid != null) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } if (event == 20) { diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 63a6143a6..33c3a4776 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class StarcomProtocol extends BaseProtocol { - public StarcomProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public StarcomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StarcomProtocolDecoder(StarcomProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java index 5ffddb318..56ab733c8 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 32f1c5a29..d010df858 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -21,19 +21,23 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class StartekProtocol extends BaseProtocol { - public StartekProtocol() { + @Inject + public StartekProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 042518cb2..8e3624cb5 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; @@ -70,17 +70,30 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("(x+),") // outputs .number("(x+)|") // power .number("(x+)") // battery - .groupBegin() - .text("|") - .expression("([^,]+)").optional() // adc + .expression("([^,]+)?") // adc .groupBegin() .text(",") .number("d,") // extended - .expression("([^,]+)?,") // fuel - .expression("([^,]+)?,?") // temperature + .expression("([^,]+)?") // fuel + .groupBegin() + .text(",") + .expression("([^,]+)?") // temperature + .groupBegin() + .text(",") + .groupBegin() + .number("(d+)?|") // rpm + .number("(d+)?|") // engine load + .number("(d+)?|") // maf flow + .number("(d+)?|") // intake pressure + .number("(d+)?|") // intake temperature + .number("(d+)?|") // throttle + .number("(d+)?|") // coolant temperature + .number("(d+)?|") // instant fuel + .number("(d+)[%L]").optional() // fuel level + .groupEnd("?") + .groupEnd("?") .groupEnd("?") .groupEnd("?") - .any() .compile(); private String decodeAlarm(int value) { @@ -181,7 +194,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { String[] adc = parser.next().split("\\|"); - for (int i = 0; i < adc.length; i++) { + for (int i = 1; i < adc.length; i++) { position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16) * 0.01); } } @@ -208,6 +221,24 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } } + if (parser.hasNext(6)) { + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); + position.set("airFlow", parser.nextInt()); + position.set("airPressure", parser.nextInt()); + if (parser.hasNext()) { + position.set("airTemp", parser.nextInt() - 40); + } + position.set(Position.KEY_THROTTLE, parser.nextInt()); + if (parser.hasNext()) { + position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); + } + if (parser.hasNext()) { + position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + } + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + } + return position; } diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 002ed86c7..af4e0d2c4 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class StbProtocol extends BaseProtocol { - public StbProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index cc985d605..641359bfd 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,12 @@ */ package org.traccar.protocol; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import javax.json.Json; import javax.json.JsonObject; @@ -42,29 +39,13 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PROPERTY = 310; public static final int MSG_ALARM = 410; - public static class Response { - @JsonProperty("msgType") - private int type; - @JsonProperty("devId") - private String deviceId; - @JsonProperty("result") - private int result; - @JsonProperty("txnNo") - private String transaction; - } - private void sendResponse( - Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) - throws JsonProcessingException { - - Response response = new Response(); - response.type = type + 1; - response.deviceId = deviceId; - response.result = 1; - response.transaction = root.getString("txnNo"); + Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) { + String response = String.format( + "{ \"msgType\": %d, \"devId\": \"%s\", \"result\": 1, \"txnNo\": \"%s\" }", + type + 1, deviceId, root.getString("txnNo")); if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Context.getObjectMapper().writeValueAsString(response), remoteAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 2711e936b..83b5db3bb 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Stl060Protocol extends BaseProtocol { - public Stl060Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Stl060Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Stl060FrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java index 7b0055aa1..dc1fa3ba3 100644 --- a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index 199885537..4253b761b 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -19,11 +19,15 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SuntechProtocol extends BaseProtocol { - public SuntechProtocol() { + @Inject + public SuntechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REBOOT_DEVICE, @@ -32,9 +36,9 @@ public class SuntechProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SuntechFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SuntechProtocolEncoder(SuntechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 2d00ea81e..047a1822a 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,13 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.config.Keys; +import org.traccar.helper.BufferUtil; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; @@ -34,10 +37,17 @@ import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.TimeZone; +import java.util.stream.Collectors; public class SuntechProtocolDecoder extends BaseProtocolDecoder { + private boolean universal; private String prefix; private int protocolType; @@ -46,10 +56,16 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { private boolean includeRpm; private boolean includeTemp; + private ByteBuf crash; + public SuntechProtocolDecoder(Protocol protocol) { super(protocol); } + public boolean getUniversal() { + return universal; + } + public String getPrefix() { return prefix; } @@ -59,8 +75,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public int getProtocolType(long deviceId) { - return Context.getIdentityManager().lookupAttributeInteger( - deviceId, getProtocolName() + ".protocolType", protocolType, false, true); + Integer value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_TYPE, deviceId); + return value != null ? value : protocolType; } public void setHbm(boolean hbm) { @@ -68,8 +84,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isHbm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".hbm", hbm, false, true); + Boolean value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_HBM, deviceId); + return value != null ? value : hbm; } public void setIncludeAdc(boolean includeAdc) { @@ -77,8 +93,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeAdc(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_ADC.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeAdc; } public void setIncludeRpm(boolean includeRpm) { @@ -86,8 +103,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeRpm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_RPM.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeRpm; } public void setIncludeTemp(boolean includeTemp) { @@ -95,8 +113,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeTemp(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_TEMPERATURE.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeTemp; } private Position decode9( @@ -185,12 +204,16 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_POWER_RESTORED; case 41: return Position.ALARM_POWER_CUT; + case 42: + return Position.ALARM_SOS; case 46: return Position.ALARM_ACCELERATION; case 47: return Position.ALARM_BRAKING; case 50: return Position.ALARM_JAMMING; + case 132: + return Position.ALARM_DOOR; default: return null; } @@ -358,7 +381,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } else if (attribute.startsWith("GTSL")) { position.set(Position.KEY_DRIVER_UNIQUE_ID, attribute.split("\\|")[4]); - } else { + } else if (attribute.contains("=")) { String[] pair = attribute.split("="); if (pair.length >= 2) { String value = pair[1].trim(); @@ -381,6 +404,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { break; } } + } else { + position.set("serial", attribute.trim()); } remaining -= attribute.length() + 1; } @@ -448,7 +473,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String type = values[index++]; - if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE")) { + if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE") && !type.equals("RES")) { return null; } @@ -461,6 +486,14 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_TYPE, type); + if (type.equals("RES")) { + getLastLocation(position, null); + position.set( + Position.KEY_RESULT, + Arrays.stream(values, index, values.length).collect(Collectors.joining(";"))); + return position; + } + int mask; if (type.equals("BLE")) { mask = 0b1100000110110; @@ -550,7 +583,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 17)) { - position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); + int input = Integer.parseInt(values[index++]); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + position.set(Position.KEY_INPUT, input); } if (BitUtil.check(mask, 18)) { @@ -559,7 +594,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (type.equals("ALT")) { if (BitUtil.check(mask, 19)) { - position.set("alertId", values[index++]); + int alertId = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlert(alertId)); } if (BitUtil.check(mask, 20)) { position.set("alertModifier", values[index++]); @@ -654,19 +690,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 11)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLatitude(value / 1000000.0); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 12)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLongitude(value / 1000000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 13)) { @@ -732,6 +760,89 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private Collection<Position> decodeCrashReport(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + if (buf.getByte(buf.readerIndex() + 3) != ';') { + return null; + } + + String[] values = buf.readCharSequence(23, StandardCharsets.US_ASCII).toString().split(";"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[1]); + if (deviceSession == null) { + return null; + } + + int currentIndex = Integer.parseInt(values[2]); + int totalIndex = Integer.parseInt(values[3]); + + if (crash == null) { + crash = Unpooled.buffer(); + } + + crash.writeBytes(buf.readSlice(buf.readableBytes() - 3)); + + if (currentIndex == totalIndex) { + + LinkedList<Position> positions = new LinkedList<>(); + + Date crashTime = new DateBuilder() + .setDate(crash.readUnsignedByte(), crash.readUnsignedByte(), crash.readUnsignedByte()) + .setTime(crash.readUnsignedByte(), crash.readUnsignedByte(), crash.readUnsignedByte()) + .getDate(); + + List<Date> times = Arrays.asList( + new Date(crashTime.getTime() - 3000), + new Date(crashTime.getTime() - 2000), + new Date(crashTime.getTime() - 1000), + new Date(crashTime.getTime() + 1000)); + + for (Date time : times) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(time); + position.setLatitude(crash.readIntLE() * 0.0000001); + position.setLongitude(crash.readIntLE() * 0.0000001); + position.setSpeed(UnitsConverter.knotsFromKph(crash.readUnsignedShort() * 0.01)); + position.setCourse(crash.readUnsignedShort() * 0.01); + + StringBuilder value = new StringBuilder("["); + for (int i = 0; i < 100; i++) { + if (value.length() > 1) { + value.append(","); + } + value.append("["); + value.append(crash.readShortLE()); + value.append(","); + value.append(crash.readShortLE()); + value.append(","); + value.append(crash.readShortLE()); + value.append("]"); + } + value.append("]"); + + position.set(Position.KEY_G_SENSOR, value.toString()); + + positions.add(position); + + } + + crash.release(); + crash = null; + + return positions; + + } else { + + return null; + + } + + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -740,14 +851,18 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (buf.getByte(buf.readerIndex() + 1) == 0) { + universal = true; return decodeBinary(channel, remoteAddress, buf); } else { - String[] values = buf.toString(StandardCharsets.US_ASCII).split(";"); + String[] values = buf.toString(StandardCharsets.US_ASCII).split(";", -1); prefix = values[0]; - if (prefix.length() < 5) { + if (prefix.equals("CRR")) { + return decodeCrashReport(channel, remoteAddress, buf); + } else if (prefix.length() < 5) { + universal = true; return decodeUniversal(channel, remoteAddress, values); } else if (prefix.endsWith("HTE")) { return decodeTravelReport(channel, remoteAddress, values); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 3b4995110..a4faacf13 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,49 +27,95 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { super(protocol); } - private String getPrefix(Channel channel) { - String prefix = "SA200CMD"; + @Override + protected Object encodeCommand(Channel channel, Command command) { + + boolean universal = false; + String prefix = "SA200"; if (channel != null) { SuntechProtocolDecoder protocolDecoder = BasePipelineFactory.getHandler(channel.pipeline(), SuntechProtocolDecoder.class); if (protocolDecoder != null) { + universal = protocolDecoder.getUniversal(); String decoderPrefix = protocolDecoder.getPrefix(); if (decoderPrefix != null && decoderPrefix.length() > 5) { - prefix = decoderPrefix.substring(0, decoderPrefix.length() - 3) + "CMD"; + prefix = decoderPrefix.substring(0, decoderPrefix.length() - 3); } } } - return prefix; - } - - @Override - protected Object encodeCommand(Channel channel, Command command) { - String prefix = getPrefix(channel); + if (universal) { + return encodeUniversalCommand(command); + } else { + return encodeLegacyCommand(prefix, command); + } + } + protected Object encodeUniversalCommand(Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, prefix + ";%s;02;Reboot\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, prefix + ";%s;02;\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - if (command.getAttributes().containsKey(Command.KEY_DATA)) { - if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - return formatCommand(command, prefix + ";%s;02;Enable%s\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); - } else { - return formatCommand(command, prefix + ";%s;02;Disable%s\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: + return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case 2: + return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case 3: + return formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); + default: + return null; } + } else { + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: + return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); + case 2: + return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + case 3: + return formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); + default: + return null; + } + } + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM: + return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM: + return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + default: + return null; + } + } + + protected Object encodeLegacyCommand(String prefix, Command command) { + switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, prefix + "CMD;%s;02;StatusReq\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL: + if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { + return formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + } else { + return formatCommand(command, prefix + "CMD;%s;02;Disable%s\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); } case Command.TYPE_ENGINE_STOP: - return formatCommand(command, prefix + ";%s;02;Enable1\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, prefix + ";%s;02;Disable1\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Disable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_ARM: - return formatCommand(command, prefix + ";%s;02;Enable2\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Enable2\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_DISARM: - return formatCommand(command, prefix + ";%s;02;Disable2\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Disable2\r", Command.KEY_UNIQUE_ID); default: return null; } diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 46625ddc7..4290b7126 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SupermateProtocol extends BaseProtocol { - public SupermateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SupermateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java index 40a25bb91..f53f0f598 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index accfa173f..7c6624f7c 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -21,12 +21,15 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SviasProtocol extends BaseProtocol { - public SviasProtocol() { + @Inject + public SviasProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -36,9 +39,9 @@ public class SviasProtocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_ALARM_REMOVE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java index 7e783f6cd..d7b126167 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java @@ -24,7 +24,7 @@ import org.traccar.helper.PatternBuilder; import java.net.SocketAddress; import java.util.regex.Pattern; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.Parser; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 5e2597b93..68cf40d84 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class SwiftechProtocol extends BaseProtocol { - public SwiftechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SwiftechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java index 8d0b31c8f..b1cff8b64 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index f5ec19094..cedac275f 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -21,22 +21,26 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class T55Protocol extends BaseProtocol { - public T55Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T55Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 230d29216..3be161fb8 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,9 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -27,6 +28,7 @@ import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.DatagramChannel; import java.util.Date; @@ -124,15 +126,41 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .expression("([01])") // ignition .compile(); + private static final Pattern PATTERN_PUBX = new PatternBuilder() + .text("$PUBX,") + .number("(d+),") // index + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .number("(dd)(dd.d+),([NS]),") // latitude + .number("(ddd)(dd.d+),([EW]),") // longitude + .number("(-?d+.d+),") // altitude + .expression("(..),") // status + .number("(d+.d+),") // horizontal accuracy + .number("d+.d+,") // vertical accuracy + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("-?d+.d+,") // vertical velocity + .expression("[^,]*,") // corrections age + .number("(d+.d+),") // hdop + .number("(d+.d+),") // vdop + .number("d+.d+,") // tdop + .number("(d+),") // satellites + .number("(d+),") // device id + .number("d+") + .text("*") + .number("xx") // checksum + .compile(); + private Position position = null; private Position decodeGprmc( DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && Context.getIdentityManager().lookupAttributeBoolean( - deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { - channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)) { + boolean ack = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ACK.withPrefix(getProtocolName()), deviceSession.getDeviceId()); + if (ack) { + channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + } } Parser parser = new Parser(PATTERN_GPRMC, sentence); @@ -300,11 +328,44 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodePubx(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_PUBX, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + + position.set(Position.KEY_INDEX, parser.nextInt()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setAltitude(parser.nextDouble()); + position.setValid(!parser.next().equals("NF")); + position.setAccuracy(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_HDOP, parser.nextDouble()); + position.set(Position.KEY_VDOP, parser.nextDouble()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } + + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = (String) msg; + String sentence = ((String) msg).trim(); DeviceSession deviceSession; @@ -320,6 +381,10 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { sentence = sentence.substring(index); } else { deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null && remoteAddress instanceof InetSocketAddress) { + String host = ((InetSocketAddress) remoteAddress).getHostString(); + deviceSession = getDeviceSession(channel, remoteAddress, host); + } } if (sentence.startsWith("$PGID")) { @@ -354,6 +419,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return decodeGpiop(deviceSession, sentence); } else if (sentence.startsWith("QZE")) { return decodeQze(channel, remoteAddress, sentence); + } else if (sentence.startsWith("$PUBX")) { + return decodePubx(channel, remoteAddress, sentence); } return null; diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index f67f82318..4bafe8c6d 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class T57Protocol extends BaseProtocol { - public T57Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T57Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T57FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java index 2a3cca3e4..d9fd1c8cf 100644 --- a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index 8b91265cb..253c3cb73 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,21 +19,32 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class T800xProtocol extends BaseProtocol { - public T800xProtocol() { + @Inject + public T800xProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); + pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); + } + }); } } diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 7f7873e50..6e09e6e3b 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -58,6 +58,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DRIVER_BEHAVIOR_1 = 0x05; // 0x2626 public static final int MSG_DRIVER_BEHAVIOR_2 = 0x06; // 0x2626 public static final int MSG_BLE = 0x10; + public static final int MSG_NETWORK_2 = 0x11; public static final int MSG_GPS_2 = 0x13; public static final int MSG_ALARM_2 = 0x14; public static final int MSG_COMMAND = 0x81; @@ -77,7 +78,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 +108,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)) @@ -145,7 +168,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return decodePosition(channel, deviceSession, buf, type, index, imei); - } else if (type == MSG_NETWORK && header == 0x2727) { + } else if (type == MSG_NETWORK && header == 0x2727 || type == MSG_NETWORK_2) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -232,6 +255,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 +309,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 +318,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; @@ -369,7 +397,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) { @@ -384,7 +412,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(status, 6)) { - position.setValid(!BitUtil.check(status, 7)); + position.setValid(true); position.setTime(readDate(buf)); position.setAltitude(buf.readFloatLE()); position.setLongitude(buf.readFloatLE()); diff --git a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java index 02c111b01..48419af2a 100644 --- a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java +++ b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; -import org.traccar.Context; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.util.List; @@ -30,14 +31,20 @@ import java.util.List; public class TaipPrefixEncoder extends MessageToMessageEncoder<ByteBuf> { private final Protocol protocol; + private Config config; public TaipPrefixEncoder(Protocol protocol) { this.protocol = protocol; } + @Inject + public void setConfig(Config config) { + this.config = config; + } + @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception { - if (Context.getConfig().getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { + if (config.getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { out.add(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[] {0x20, 0x20, 0x06, 0x00}), msg.retain())); } else { out.add(msg.retain()); diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index 0966cfd7c..943ec98c5 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TaipProtocol extends BaseProtocol { - public TaipProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TaipProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); @@ -35,9 +39,9 @@ public class TaipProtocol extends BaseProtocol { pipeline.addLast(new TaipProtocolDecoder(TaipProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index ec0ce1931..e5e84b7c4 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index 0cffb452d..191dd9ccc 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TechTltProtocol extends BaseProtocol { - public TechTltProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TechTltProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechTltProtocolDecoder(TechTltProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index 17f5c80fa..94efacc63 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -110,7 +110,7 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextInt(), parser.nextInt()))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), parser.nextInt(), parser.nextInt()))); return position; } diff --git a/src/main/java/org/traccar/protocol/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..265a3eb64 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -15,20 +15,23 @@ */ 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; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TechtoCruzProtocol extends BaseProtocol { - public TechtoCruzProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TechtoCruzProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new TechtoCruzFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechtoCruzProtocolDecoder(TechtoCruzProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java index 6b9f0edb6..09efcb7d4 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index c1d78e6f5..54e860d79 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TekProtocol extends BaseProtocol { - public TekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TekFrameDecoder()); pipeline.addLast(new TekProtocolDecoder(TekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java index 33ff51d2d..819c7e819 100644 --- a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 838da9df1..9e9cbb50e 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TelemaxProtocol extends BaseProtocol { - public TelemaxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelemaxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java index 9369ab101..f6f6f5379 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 991befa19..9ef7864ca 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TelicProtocol extends BaseProtocol { - public TelicProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelicProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TelicFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java index a4f9e2989..9681dc565 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java index c30fee6e3..3a0962584 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ public class TeltonikaFrameDecoder extends BaseFrameDecoder { ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { while (buf.isReadable() && buf.getByte(buf.readerIndex()) == (byte) 0xff) { - buf.skipBytes(1); + return buf.readRetainedSlice(1); } if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index 5817b86be..38283cb64 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -18,24 +18,28 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TeltonikaProtocol extends BaseProtocol { - public TeltonikaProtocol() { + @Inject + public TeltonikaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaFrameDecoder()); pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89ae48b3a..929eca8aa 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,8 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.model.Device; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -39,11 +39,15 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private static final int IMAGE_PACKET_MAX = 2048; + private static final Map<Integer, Map<Set<String>, BiConsumer<Position, ByteBuf>>> PARAMETERS = new HashMap<>(); + private final boolean connectionless; private boolean extended; private final Map<Long, ByteBuf> photos = new HashMap<>(); @@ -55,7 +59,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { public TeltonikaProtocolDecoder(Protocol protocol, boolean connectionless) { super(protocol); this.connectionless = connectionless; - this.extended = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + this.extended = getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); } private void parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { @@ -116,7 +124,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return printable; } - private void decodeSerial(Channel channel, SocketAddress remoteAddress, Position position, ByteBuf buf) { + private void decodeSerial( + Channel channel, SocketAddress remoteAddress, DeviceSession deviceSession, Position position, ByteBuf buf) { getLastLocation(position, null); @@ -145,10 +154,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, photoId, photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); } else { - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } @@ -181,191 +189,193 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private long readValue(ByteBuf buf, int length, boolean signed) { + private long readValue(ByteBuf buf, int length) { switch (length) { case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); + return buf.readUnsignedByte(); case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); + return buf.readUnsignedShort(); case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); + return buf.readUnsignedInt(); default: return buf.readLong(); } } - private void decodeOtherParameter(Position position, int id, ByteBuf buf, int length) { - switch (id) { - case 1: - case 2: - case 3: - case 4: - position.set("di" + id, readValue(buf, length, false)); - break; - case 9: - position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); - break; - case 10: - position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); - break; - case 16: - position.set(Position.KEY_ODOMETER, readValue(buf, length, false)); - break; - case 17: - position.set("axisX", readValue(buf, length, true)); - break; - case 18: - position.set("axisY", readValue(buf, length, true)); - break; - case 19: - position.set("axisZ", readValue(buf, length, true)); - break; - case 21: - position.set(Position.KEY_RSSI, readValue(buf, length, false)); - break; - case 25: - case 26: - case 27: - case 28: - position.set(Position.PREFIX_TEMP + (id - 24 + 4), readValue(buf, length, true) * 0.1); - break; - case 66: - position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 72: - case 73: - case 74: - position.set(Position.PREFIX_TEMP + (id - 71), readValue(buf, length, true) * 0.1); - break; - case 78: - long driverUniqueId = readValue(buf, length, false); - if (driverUniqueId != 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); - } - break; - case 80: - position.set("workMode", readValue(buf, length, false)); - break; - case 90: - position.set(Position.KEY_DOOR, readValue(buf, length, false)); - break; - case 115: - position.set(Position.KEY_COOLANT_TEMP, readValue(buf, length, true) * 0.1); - break; - case 179: - position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); - break; - case 180: - position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); - break; - case 181: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); - break; - case 182: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); - break; - case 199: - position.set(Position.KEY_ODOMETER_TRIP, readValue(buf, length, false)); - break; - case 236: - if (readValue(buf, length, false) == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - break; - case 239: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); - break; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); - break; - case 241: - position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); - break; - case 253: - switch ((int) readValue(buf, length, false)) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; - } - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } + private static void register(int id, Set<String> models, BiConsumer<Position, ByteBuf> handler) { + PARAMETERS.computeIfAbsent(id, key -> new HashMap<>()).put(models, handler); + } + + static { + var fmbXXX = Set.of( + "FMB001", "FMB010", "FMB002", "FMB020", "FMB003", "FMB110", "FMB120", "FMB122", "FMB125", "FMB130", + "FMB140", "FMU125", "FMB900", "FMB920", "FMB962", "FMB964", "FM3001", "FMB202", "FMB204", "FMB206", + "FMT100", "MTB100", "FMP100", "MSP500"); + + register(1, null, (p, b) -> p.set(Position.PREFIX_IN + 1, b.readUnsignedByte() > 0)); + register(2, null, (p, b) -> p.set(Position.PREFIX_IN + 2, b.readUnsignedByte() > 0)); + register(3, null, (p, b) -> p.set(Position.PREFIX_IN + 3, b.readUnsignedByte() > 0)); + register(4, null, (p, b) -> p.set(Position.PREFIX_IN + 4, b.readUnsignedByte() > 0)); + register(9, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 1, b.readUnsignedShort() * 0.001)); + register(10, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 2, b.readUnsignedShort() * 0.001)); + register(11, fmbXXX, (p, b) -> p.set(Position.KEY_ICCID, String.valueOf(b.readLong()))); + register(12, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_USED, b.readUnsignedInt() * 0.001)); + register(13, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.01)); + register(16, null, (p, b) -> p.set(Position.KEY_ODOMETER, b.readUnsignedInt())); + register(17, null, (p, b) -> p.set("axisX", b.readShort())); + register(18, null, (p, b) -> p.set("axisY", b.readShort())); + register(19, null, (p, b) -> p.set("axisZ", b.readShort())); + register(21, null, (p, b) -> p.set(Position.KEY_RSSI, b.readUnsignedByte())); + register(24, fmbXXX, (p, b) -> p.setSpeed(UnitsConverter.knotsFromKph(b.readUnsignedShort()))); + register(25, null, (p, b) -> p.set("bleTemp1", b.readShort() * 0.01)); + register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); + register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); + register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); + register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); + register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); + register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readInt() * 0.1)); + register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readInt() * 0.1)); + register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readInt() * 0.1)); + register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readInt() * 0.1)); + register(78, null, (p, b) -> { + long driverUniqueId = b.readLong(); + if (driverUniqueId > 0) { + p.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); + } + }); + register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); + register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); + register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); + register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); + register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); + register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); + register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); + register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); + register(205, fmbXXX, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(206, fmbXXX, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(236, null, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); + }); + register(239, null, (p, b) -> p.set(Position.KEY_IGNITION, b.readUnsignedByte() > 0)); + register(240, null, (p, b) -> p.set(Position.KEY_MOTION, b.readUnsignedByte() > 0)); + register(241, null, (p, b) -> p.set(Position.KEY_OPERATOR, b.readUnsignedInt())); + register(253, null, (p, b) -> { + switch (b.readUnsignedByte()) { + case 1: + p.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 2: + p.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 3: + p.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + break; + } + }); } private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: - position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); + position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length)); break; case 2: - position.set("usbConnected", readValue(buf, length, false) == 1); + position.set("usbConnected", readValue(buf, length) == 1); break; case 5: - position.set("uptime", readValue(buf, length, false)); + position.set("uptime", readValue(buf, length)); break; case 20: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_HDOP, readValue(buf, length) * 0.1); break; case 21: - position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_VDOP, readValue(buf, length) * 0.1); break; case 22: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_PDOP, readValue(buf, length) * 0.1); break; case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + position.set(Position.KEY_BATTERY, readValue(buf, length) * 0.001); break; case 221: - position.set("button", readValue(buf, length, false)); + position.set("button", readValue(buf, length)); break; case 222: - if (readValue(buf, length, false) == 1) { + if (readValue(buf, length) == 1) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } break; case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + position.set(Position.KEY_MOTION, readValue(buf, length) == 1); break; case 244: - position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); + position.set(Position.KEY_ROAMING, readValue(buf, length) == 1); break; default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + position.set(Position.PREFIX_IO + id, readValue(buf, length)); break; } } - private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec) { + private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec, String model) { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { - decodeOtherParameter(position, id, buf, length); + int index = buf.readerIndex(); + boolean decoded = false; + for (var entry : PARAMETERS.getOrDefault(id, new HashMap<>()).entrySet()) { + if (entry.getKey() == null || model != null && entry.getKey().contains(model)) { + entry.getValue().accept(position, buf); + decoded = true; + break; + } + } + if (decoded) { + buf.readerIndex(index + length); + } else { + position.set(Position.PREFIX_IO + id, readValue(buf, length)); + } + } + } + + private void decodeCell( + Position position, Network network, String mncKey, String lacKey, String cidKey, String rssiKey) { + if (position.hasAttribute(mncKey) && position.hasAttribute(lacKey) && position.hasAttribute(cidKey)) { + CellTower cellTower = CellTower.from( + getConfig().getInteger(Keys.GEOLOCATION_MCC), + ((Number) position.getAttributes().remove(mncKey)).intValue(), + ((Number) position.getAttributes().remove(lacKey)).intValue(), + ((Number) position.getAttributes().remove(cidKey)).longValue()); + cellTower.setSignalStrength(((Number) position.getAttributes().remove(rssiKey)).intValue()); + network.addCellTower(cellTower); } } - private void decodeNetwork(Position position) { - long cid = position.getLong(Position.PREFIX_IO + 205); - int lac = position.getInteger(Position.PREFIX_IO + 206); - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromLacCid(lac, cid); - long operator = position.getInteger(Position.KEY_OPERATOR); - if (operator != 0) { - cellTower.setOperator(operator); + private void decodeNetwork(Position position, String model) { + if ("TAT100".equals(model)) { + Network network = new Network(); + decodeCell(position, network, "io1200", "io287", "io288", "io289"); + decodeCell(position, network, "io1201", "io290", "io291", "io292"); + decodeCell(position, network, "io1202", "io293", "io294", "io295"); + decodeCell(position, network, "io1203", "io296", "io297", "io298"); + if (network.getCellTowers() != null) { + position.setNetwork(network); + } + } else { + Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer lac = (Integer) position.getAttributes().remove("lac"); + if (cid != null && lac != null) { + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); + long operator = position.getInteger(Position.KEY_OPERATOR); + if (operator >= 1000) { + cellTower.setOperator(operator); + } + position.setNetwork(new Network(cellTower)); } - position.setNetwork(new Network(cellTower)); } } @@ -384,7 +394,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeLocation(Position position, ByteBuf buf, int codec) { + private void decodeLocation(Position position, ByteBuf buf, int codec, String model) { int globalMask = 0x0f; @@ -422,7 +432,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(locationMask, 5)) { - CellTower cellTower = CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromLacCid( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); if (BitUtil.check(locationMask, 6)) { cellTower.setSignalStrength((int) buf.readUnsignedByte()); @@ -480,7 +491,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec, model); } } @@ -488,7 +499,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec, model); } } @@ -496,7 +507,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec, model); } } @@ -504,7 +515,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec, model); } } @@ -558,7 +569,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - decodeNetwork(position); + decodeNetwork(position, model); } @@ -574,10 +585,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { int count = buf.readUnsignedByte(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { return null; } + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); for (int i = 0; i < count; i++) { Position position = new Position(getProtocolName()); @@ -597,9 +608,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ByteBufUtil.hexDump(buf.readSlice(length))); } } else if (codec == CODEC_12) { - decodeSerial(channel, remoteAddress, position, buf); + decodeSerial(channel, remoteAddress, deviceSession, position, buf); } else { - decodeLocation(position, buf, codec); + decodeLocation(position, buf, codec, model); } if (!position.getOutdated() || !position.getAttributes().isEmpty()) { @@ -636,9 +647,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - if (buf.getUnsignedShort(0) > 0) { + if (buf.readableBytes() == 1 && buf.readUnsignedByte() == 0xff) { + return null; + } else if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { buf.skipBytes(4); @@ -648,7 +661,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShort(); // length buf.readUnsignedShort(); // packet id diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java new file mode 100644 index 000000000..73219cc5e --- /dev/null +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -0,0 +1,42 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class TeraTrackProtocol extends BaseProtocol { + + @Inject + public TeraTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new JsonFrameDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new TeraTrackProtocolDecoder(TeraTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java new file mode 100644 index 000000000..313210f63 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -0,0 +1,79 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.session.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { + + public TeraTrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + JsonObject json = Json.createReader(new StringReader((String) msg)).readObject(); + + String deviceId = json.getString("MDeviceID"); + String imei = json.getString("IMEI"); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId, imei); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(json.getString("DateTime"))); + + position.setValid(true); + position.setLatitude(Double.parseDouble(json.getString("Latitude"))); + position.setLongitude(Double.parseDouble(json.getString("Longitude"))); + position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(json.getString("Speed")))); + + position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); + position.set(Position.KEY_BLOCKED, json.getString("LockOpen").equals("0")); + position.set(Position.KEY_DRIVER_UNIQUE_ID, json.getString("CardNo")); + position.set(Position.KEY_ALARM, json.getString("LowPower").equals("1") ? Position.ALARM_LOW_POWER : null); + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(json.getString("Power"))); + position.set(Position.KEY_RSSI, Integer.parseInt(json.getString("GSM"))); + + if (channel != null && json.getString("MessageAck").equals("1")) { + channel.writeAndFlush(new NetworkMessage("{01}", remoteAddress)); + } + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index ece1b0544..38bf078aa 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ThinkPowerProtocol extends BaseProtocol { - public ThinkPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); pipeline.addLast(new ThinkPowerProtocolDecoder(ThinkPowerProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index b3f943078..e7ab23e5b 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ 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.helper.BufferUtil; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; @@ -64,8 +65,8 @@ public class ThinkPowerProtocolDecoder extends BaseProtocolDecoder { switch (type) { case 0x01: position.setValid(true); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.01); break; diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index ca1237cef..782b0a352 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class ThinkRaceProtocol extends BaseProtocol { - public ThinkRaceProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkRaceProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); pipeline.addLast(new ThinkRaceProtocolDecoder(ThinkRaceProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java index 0928b25e0..796b726ea 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -104,7 +104,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedByte()); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); return position; diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocol.java b/src/main/java/org/traccar/protocol/ThurayaProtocol.java new file mode 100644 index 000000000..f709a1183 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class ThurayaProtocol extends BaseProtocol { + + @Inject + public ThurayaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); + pipeline.addLast(new ThurayaProtocolDecoder(ThurayaProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java new file mode 100644 index 000000000..a287ece34 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java @@ -0,0 +1,195 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; + +public class ThurayaProtocolDecoder extends BaseProtocolDecoder { + + public ThurayaProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_EVENT = 0x5101; + public static final int MSG_PERIODIC_REPORT = 0x7101; + public static final int MSG_SETTING_RESPONSE = 0x8115; + public static final int MSG_ACK = 0x9901; + + private static int checksum(ByteBuffer buf) { + int crc = 0; + while (buf.hasRemaining()) { + crc += buf.get(); + } + crc = ~crc; + crc += 1; + return crc; + } + + private void sendResponse(Channel channel, SocketAddress remoteAddress, long id, int type) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeCharSequence("#T", StandardCharsets.US_ASCII); + response.writeShort(15); // length + response.writeShort(MSG_ACK); + response.writeInt((int) id); + response.writeShort(type); + response.writeShort(1); // server ok + response.writeShort(checksum(response.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + private void decodeLocation(ByteBuf buf, Position position) { + + position.setValid(true); + + DateBuilder dateBuilder = new DateBuilder(); + + int date = buf.readInt(); + dateBuilder.setDay(date % 100); + date /= 100; + dateBuilder.setMonth(date % 100); + date /= 100; + dateBuilder.setYear(date); + + int time = buf.readInt(); + dateBuilder.setSecond(time % 100); + time /= 100; + dateBuilder.setMinute(time % 100); + time /= 100; + dateBuilder.setHour(time); + + position.setTime(dateBuilder.getDate()); + + position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readInt() / 1000000.0); + + int data = buf.readUnsignedShort(); + + int ignition = BitUtil.from(data, 12); + if (ignition == 1) { + position.set(Position.KEY_IGNITION, true); + } else if (ignition == 2) { + position.set(Position.KEY_IGNITION, false); + } + + position.setCourse(BitUtil.to(data, 12)); + position.setSpeed(buf.readShort()); + + position.set(Position.KEY_RPM, buf.readShort()); + + position.set("data", readString(buf)); + } + + private String decodeAlarm(int event) { + switch (event) { + case 10: + return Position.ALARM_VIBRATION; + case 11: + return Position.ALARM_OVERSPEED; + case 12: + return Position.ALARM_POWER_CUT; + case 13: + return Position.ALARM_LOW_BATTERY; + case 18: + return Position.ALARM_GPS_ANTENNA_CUT; + case 20: + return Position.ALARM_ACCELERATION; + case 21: + return Position.ALARM_BRAKING; + default: + return null; + } + } + + private String readString(ByteBuf buf) { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + CharSequence value = buf.readCharSequence(endIndex - buf.readerIndex(), StandardCharsets.US_ASCII); + buf.readUnsignedByte(); // delimiter + return value.toString(); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(2); // service + buf.readUnsignedShort(); // length + int type = buf.readUnsignedShort(); + long id = buf.readUnsignedInt(); + + sendResponse(channel, remoteAddress, id, type); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + + if (type == MSG_EVENT) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + int event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set("eventData", readString(buf)); + + return position; + + } else if (type == MSG_PERIODIC_REPORT) { + + List<Position> positions = new LinkedList<>(); + + int count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + positions.add(position); + + } + + return positions; + + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 9f2463cd6..150e83ab3 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Tk102Protocol extends BaseProtocol { - public Tk102Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tk102Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); pipeline.addLast(new Tk102ProtocolDecoder(Tk102Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java index da0c6928b..af29fbc21 100644 --- a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index ff0bedfb7..cf09886f5 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -21,11 +21,15 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Tk103Protocol extends BaseProtocol { - public Tk103Protocol() { + @Inject + public Tk103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_GET_DEVICE_STATUS, @@ -45,9 +49,9 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Tk103FrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -55,9 +59,9 @@ public class Tk103Protocol extends BaseProtocol { pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index ff33cb103..b343c3b33 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -36,11 +35,15 @@ import java.util.regex.Pattern; public class Tk103ProtocolDecoder extends BaseProtocolDecoder { - private final boolean decodeLow; + private boolean decodeLow; public Tk103ProtocolDecoder(Protocol protocol) { super(protocol); - decodeLow = Context.getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + decodeLow = getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() @@ -96,6 +99,16 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_CELL = new PatternBuilder() + .text("(") + .number("(d{12})") // device id + .expression(".{4}") // type + .number("(?:d{15})?,") // imei + .expression("(.+),") // cell + .number("(d{8})") // odometer + .text(")") + .compile(); + private static final Pattern PATTERN_NETWORK = new PatternBuilder() .text("(").optional() .number("(d{12})") // device id @@ -294,6 +307,39 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeCell(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_CELL, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + Network network = new Network(); + + String[] cells = parser.next().split("\n"); + for (String cell : cells) { + String[] values = cell.substring(1, cell.length() - 1).split(","); + network.addCellTower(CellTower.from( + Integer.parseInt(values[0]), Integer.parseInt(values[1]), + Integer.parseInt(values[2]), Integer.parseInt(values[3]))); + } + + position.setNetwork(network); + + position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); + + return position; + } + private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_NETWORK, sentence); if (!parser.matches()) { @@ -419,7 +465,9 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } - if (sentence.contains("ZC20")) { + if (sentence.indexOf('{') > 0 && sentence.indexOf('}') > 0) { + return decodeCell(channel, remoteAddress, sentence); + } else if (sentence.contains("ZC20")) { return decodeBattery(channel, remoteAddress, sentence); } else if (sentence.contains("BZ00")) { return decodeNetwork(channel, remoteAddress, sentence); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index 5d7e63920..e3e1ae961 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -16,10 +16,11 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import org.traccar.Protocol; public class Tk103ProtocolEncoder extends StringProtocolEncoder { @@ -42,12 +43,12 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); initDevicePassword(command, "123456"); - if (alternative) { + if (alternative || forceAlternative) { switch (command.getType()) { case Command.TYPE_CUSTOM: return formatAlt(command, "%s", Command.KEY_DATA); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 12fd92afa..b10271f7d 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Tlt2hProtocol extends BaseProtocol { - public Tlt2hProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tlt2hProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index ad7dfa886..e85bdf9b3 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.model.CellTower; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -55,6 +56,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_POSITION = new PatternBuilder() .text("#") .number("(?:(dd)|x*)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$GPRMC,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("([AVL]),") // validity @@ -71,6 +78,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_WIFI = new PatternBuilder() .text("#") .number("(?:(dd)|x+)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$WIFI,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("[AVL],") // validity @@ -168,6 +181,13 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); } + if (parser.hasNext(4)) { + Network network = new Network(); + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + position.setNetwork(network); + } + DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); @@ -191,11 +211,16 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); + Network network = new Network(); + if (parser.hasNext(4)) { + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + } + DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); String[] values = parser.next().split(","); - Network network = new Network(); for (int i = 0; i < values.length / 2; i++) { String mac = values[i * 2 + 1].replaceAll("(..)", "$1:").substring(0, 17); network.addWifiAccessPoint(WifiAccessPoint.from(mac, Integer.parseInt(values[i * 2]))); diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 94f5da94f..9d83388c9 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -19,13 +19,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TlvProtocol extends BaseProtocol { - public TlvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TlvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new TlvProtocolDecoder(TlvProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java index 36cf7859f..7870c778a 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index 020332ce7..e078c425b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -20,13 +20,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TmgProtocol extends BaseProtocol { - public TmgProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TmgProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TmgFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java index d27849f8c..00dc2a09b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 303072bdb..339d2fc8d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TopflytechProtocol extends BaseProtocol { - public TopflytechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TopflytechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java index 6de053c32..92a7b5c9d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index d28afbf94..b15373d71 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -18,16 +18,20 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TopinProtocol extends BaseProtocol { - public TopinProtocol() { + @Inject + public TopinProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SOS_NUMBER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); pipeline.addLast(new TopinProtocolDecoder(TopinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 267bce562..a1d5481db 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; @@ -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(); @@ -190,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()); } @@ -207,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; @@ -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/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index f8cda8358..9ab36fd0b 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -20,18 +20,39 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TotemProtocol extends BaseProtocol { - public TotemProtocol() { + @Inject + public TotemProtocol(Config config) { setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_FACTORY_RESET, + Command.TYPE_GET_VERSION, + Command.TYPE_POSITION_SINGLE, + Command.TYPE_ENGINE_RESUME, + Command.TYPE_ENGINE_STOP + ); + + setTextCommandEncoder(new TotemProtocolSmsEncoder(this)); + setSupportedTextCommands( + Command.TYPE_CUSTOM, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_FACTORY_RESET, + Command.TYPE_GET_VERSION, + Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP ); - addServer(new TrackerServer(false, getName()) { + + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TotemFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 58c66031e..9d0d794f8 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -140,8 +140,12 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(x{8})") // status .number("(dd)(dd)(dd)") // date (yymmdd) .number("(dd)(dd)(dd)") // time (hhmmss) + .groupBegin() .number("(dd)") // battery .number("(dd)") // external power + .or() + .number("(ddd)") // battery + .groupEnd() .number("(dddd)") // adc 1 .groupBegin() .groupBegin() @@ -166,6 +170,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(d{7})") // odometer .number("(dd)(dd.dddd)([NS])") // latitude .number("(ddd)(dd.dddd)([EW])") // longitude + .number("dddd").optional() // temperature .number("dddd") // serial number .number("xx") // checksum .any() @@ -320,7 +325,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int lac = parser.nextHexInt(0); int cid = parser.nextHexInt(0); if (lac != 0 && cid != 0) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } position.set(Position.PREFIX_TEMP + 1, parser.next()); @@ -346,7 +351,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 2, parser.next()); position.setNetwork(new Network( - CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + CellTower.fromLacCid(getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); position.setValid(parser.next().equals("A")); position.set(Position.KEY_SATELLITES, parser.nextInt()); @@ -379,8 +384,13 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setTime(parser.nextDateTime()); - position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); - position.set(Position.KEY_POWER, parser.nextDouble()); + if (parser.hasNext(2)) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); + position.set(Position.KEY_POWER, parser.nextDouble()); + } + if (parser.hasNext()) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.01); + } position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); @@ -403,7 +413,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int mcc = parser.nextInt(); cellTower = CellTower.from(mcc, mnc, lac, cid); } else { - cellTower = CellTower.fromLacCid(lac, cid); + cellTower = CellTower.fromLacCid(getConfig(), lac, cid); } position.set(Position.KEY_SATELLITES, parser.nextInt()); cellTower.setSignalStrength(parser.nextInt()); diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index a96dd1ee3..4b22ade03 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,6 +19,7 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; import org.traccar.Protocol; +import org.traccar.helper.Checksum; public class TotemProtocolEncoder extends StringProtocolEncoder { @@ -26,20 +27,41 @@ public class TotemProtocolEncoder extends StringProtocolEncoder { super(protocol); } - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, "000000"); - + public static String formatContent(Command command) { switch (command.getType()) { + case Command.TYPE_CUSTOM: + return String.format("%s,%s", + command.getAttributes().get(Command.KEY_DEVICE_PASSWORD), + command.getAttributes().get(Command.KEY_DATA) + ); + case Command.TYPE_REBOOT_DEVICE: + return String.format("%s,006", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_FACTORY_RESET: + return String.format("%s,007", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_GET_VERSION: + return String.format("%s,056", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_POSITION_SINGLE: + return String.format("%s,012", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "*%s,025,C,1#", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,025,C,1", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "*%s,025,C,0#", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,025,C,0", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); default: return null; } } + @Override + protected Object encodeCommand(Command command) { + + initDevicePassword(command, "000000"); + + String commandString = formatContent(command); + String builtCommand = String.format("$$%04dCF%s", 10 + commandString.getBytes().length, commandString); + + return String.format("%s%02X", builtCommand, Checksum.xor(builtCommand)); + + } + } diff --git a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java new file mode 100644 index 000000000..8656f8a5c --- /dev/null +++ b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Irving Gonzalez + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.StringProtocolEncoder; +import org.traccar.model.Command; +import org.traccar.Protocol; + +public class TotemProtocolSmsEncoder extends StringProtocolEncoder { + + public TotemProtocolSmsEncoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object encodeCommand(Command command) { + + initDevicePassword(command, "000000"); + + return String.format("*%s#", TotemProtocolEncoder.formatContent(command)); + } + +} diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index 1b71db03f..615fdab28 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -21,22 +21,26 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Tr20Protocol extends BaseProtocol { - public Tr20Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr20Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java index 2f11bd152..0e1c7568b 100644 --- a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; @@ -52,7 +52,7 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)(dd.d+),") // longitude .number("(d+),") // speed .number("(d+),") // course - .number("(?:NA|[FC]?(-?d+)[^,]*),") // temperature + .number("(?:NA|[BFC]?(-?d+)[^,]*),") // temperature .number("(x{8}),") // status .number("(d+)") // event .any() diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index b70521b35..162cbe651 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -21,22 +21,26 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Tr900Protocol extends BaseProtocol { - public Tr900Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr900Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java index 319194c21..da0e8d292 100644 --- a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 5da5abd64..4236144a3 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TrackboxProtocol extends BaseProtocol { - public TrackboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrackboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java index db8022738..10483d445 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index bda5df10f..b7637e6f3 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TrakMateProtocol extends BaseProtocol { - public TrakMateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrakMateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java index 4d5cb18f5..b1f50dc10 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index f683ccc5d..79a59abd3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TramigoProtocol extends BaseProtocol { - public TramigoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TramigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TramigoFrameDecoder()); pipeline.addLast(new TramigoProtocolDecoder(TramigoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index e42e2f670..21dd78da3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateUtil; diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index 99a164cf1..e67afbda2 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TrvProtocol extends BaseProtocol { - public TrvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index 05312b820..9df29ae1b 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -59,7 +59,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode - .number("(?:[0-2]{3})?,") + .number("(?:d{3,5})?,") .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -183,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) { + } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03") || type.equals("YP14")) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index 66a13da9e..ab109e274 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Tt8850Protocol extends BaseProtocol { - public Tt8850Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tt8850Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java index 1010528c4..cbc983000 100644 --- a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index 32e9acae1..cc3bc9b52 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class TytanProtocol extends BaseProtocol { - public TytanProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TytanProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java index 93d3a63d2..6169e0545 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index 6e855d138..d25757b63 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -15,18 +15,21 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import javax.inject.Inject; public class TzoneProtocol extends BaseProtocol { - public TzoneProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TzoneProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); pipeline.addLast(new TzoneProtocolDecoder(TzoneProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 249915b39..8e84a6781 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -17,10 +17,13 @@ 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.session.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,11 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; public class TzoneProtocolDecoder extends BaseProtocolDecoder { @@ -37,6 +45,20 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private void sendResponse(Channel channel, SocketAddress remoteAddress, int index) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + String ack = String.format("@ACK,%d#", index); + String time = String.format("@UTC time:%s", dateFormat.format(new Date())); + + ByteBuf response = Unpooled.copiedBuffer(ack + time, StandardCharsets.US_ASCII); + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + private String decodeAlarm(Short value) { switch (value) { case 0x01: @@ -261,7 +283,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (hardware == 0x10A || hardware == 0x10B || hardware == 0x406) { position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); } else if (hardware == 0x407) { @@ -348,6 +370,10 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } + if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); + } + return position; } diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index dfe5235f0..57fc47644 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -18,16 +18,20 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class UlbotechProtocol extends BaseProtocol { - public UlbotechProtocol() { + @Inject + public UlbotechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new UlbotechFrameDecoder()); pipeline.addLast(new UlbotechProtocolEncoder(UlbotechProtocol.this)); pipeline.addLast(new UlbotechProtocolDecoder(UlbotechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index 7fec0bf8b..c9b35158e 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -37,6 +37,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class UlbotechProtocolDecoder extends BaseProtocolDecoder { @@ -214,16 +215,17 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); long seconds = buf.readUnsignedInt() & 0x7fffffffL; seconds += 946684800L; // 2000-01-01 00:00 - seconds -= deviceSession.getTimeZone().getRawOffset() / 1000; + seconds -= timeZone.getRawOffset() / 1000; Date time = new Date(seconds * 1000); boolean hasLocation = false; diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index 4e60ffeb6..e27088594 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -20,13 +20,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class UproProtocol extends BaseProtocol { - public UproProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UproProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new UproProtocolDecoder(UproProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index 9f236a7e5..ed714e464 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -67,12 +67,11 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setValid(true); position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); int flags = parser.nextInt(0); - position.setValid(BitUtil.check(flags, 0)); + position.setValid(!BitUtil.check(flags, 0)); if (!BitUtil.check(flags, 1)) { position.setLatitude(-position.getLatitude()); } diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 41b59d829..3de4a4732 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class UuxProtocol extends BaseProtocol { - public UuxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UuxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 1)); pipeline.addLast(new UuxProtocolDecoder(UuxProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java index 1081fa811..b9065e7f3 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index dc0922cd4..53bca849c 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -21,22 +21,26 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class V680Protocol extends BaseProtocol { - public V680Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public V680Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java index 40267022b..237aea39b 100644 --- a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 2c6af45a8..5296402b4 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -21,13 +21,17 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class VisiontekProtocol extends BaseProtocol { - public VisiontekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VisiontekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java index c4787bda2..9ab871bfe 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index 0fed30e13..dd739f0d9 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -19,15 +19,19 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class VnetProtocol extends BaseProtocol { - public VnetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VnetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 4, 2, 12, 0, true)); pipeline.addLast(new VnetProtocolDecoder(VnetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java index 1ee00bd3f..048c89e1e 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index 2a9ef6ab5..efb5fe2fd 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Vt200Protocol extends BaseProtocol { - public Vt200Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Vt200Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Vt200FrameDecoder()); pipeline.addLast(new Vt200ProtocolDecoder(Vt200Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java index 84ad09caa..a8fc801e7 100644 --- a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 2826a86e6..482ab4a37 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -15,26 +15,29 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; -import io.netty.handler.codec.string.StringDecoder; +import javax.inject.Inject; public class VtfmsProtocol extends BaseProtocol { - public VtfmsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VtfmsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new VtfmsFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java index 17fac4311..bf0cdcb51 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index 6dc3bf9fb..600f81328 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -18,11 +18,15 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class WatchProtocol extends BaseProtocol { - public WatchProtocol() { + @Inject + public WatchProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -40,9 +44,9 @@ public class WatchProtocol extends BaseProtocol { Command.TYPE_VOICE_MESSAGE, Command.TYPE_SET_TIMEZONE, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WatchFrameDecoder()); pipeline.addLast(new WatchProtocolEncoder(WatchProtocol.this)); pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 4990cfd65..142d1b64f 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,12 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.BufferUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -41,7 +39,7 @@ import java.util.regex.Pattern; public class WatchProtocolDecoder extends BaseProtocolDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WatchProtocolDecoder.class); + private ByteBuf audio; public WatchProtocolDecoder(Protocol protocol) { super(protocol); @@ -89,6 +87,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_EXIT; } else if (BitUtil.check(status, 2)) { return Position.ALARM_GEOFENCE_ENTER; + } else if (BitUtil.check(status, 14)) { + return Position.ALARM_POWER_CUT; } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { @@ -142,14 +142,21 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); int cellCount = Integer.parseInt(values[index++]); - index += 1; // timing advance - int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from(mcc, mnc, - Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), - Integer.parseInt(values[index++]))); + if (cellCount > 0) { + index += 1; // timing advance + int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + + for (int i = 0; i < cellCount; i++) { + int lac = Integer.parseInt(values[index++]); + int cid = Integer.parseInt(values[index++]); + String rssi = values[index++]; + if (!rssi.isEmpty()) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); + } else { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } + } } if (index < values.length && !values[index].isEmpty()) { @@ -157,8 +164,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < wifiCount; i++) { index += 1; // wifi name - network.addWifiAccessPoint(WifiAccessPoint.from( - values[index++], Integer.parseInt(values[index++]))); + String macAddress = values[index++]; + String rssi = values[index++]; + if (!macAddress.isEmpty() && !macAddress.equals("0") && !rssi.isEmpty()) { + network.addWifiAccessPoint(WifiAccessPoint.from(macAddress, Integer.parseInt(rssi))); + } } } @@ -253,6 +263,9 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); if (type.startsWith("AL")) { + if (position != null) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } sendResponse(channel, id, index, "AL"); } @@ -305,17 +318,41 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int timeIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); buf.readerIndex(timeIndex + 12 + 2); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(id, buf, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(id, buf, "jpg")); return position; + } else if (type.equals("JXTK")) { + + int dataIndex = BufferUtil.indexOf(buf, buf.readerIndex(), buf.writerIndex(), (byte) ',', 4) + 1; + String[] values = buf.readCharSequence( + dataIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString().split(","); + + int current = Integer.parseInt(values[2]); + int total = Integer.parseInt(values[3]); + + if (audio == null) { + audio = Unpooled.buffer(); + } + audio.writeBytes(buf); + + sendResponse(channel, id, index, "JXTKR,1"); + + if (current < total) { + return null; + } else { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + position.set(Position.KEY_AUDIO, writeMediaFile(id, audio, "amr")); + audio.release(); + audio = null; + return position; + } + } else if (type.equals("TK")) { if (buf.readableBytes() == 1) { - byte result = buf.readByte(); - if (result != '1') { - LOGGER.warn(type + "," + result); - } return null; } @@ -324,7 +361,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr")); + position.set(Position.KEY_AUDIO, writeMediaFile(id, buf, "amr")); return position; diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java index f1904ea4d..14ebe2852 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java @@ -67,6 +67,9 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin if (decoder != null) { hasIndex = decoder.getHasIndex(); manufacturer = decoder.getManufacturer(); + if (manufacturer.equals("3G")) { + manufacturer = "SG"; + } } } diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index cb6ea5319..a744349cd 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -15,32 +15,34 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class WialonProtocol extends BaseProtocol { - public WialonProtocol() { + @Inject + public WialonProtocol(Config config) { setSupportedDataCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_SEND_USSD, Command.TYPE_IDENTIFICATION, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); @@ -52,11 +54,11 @@ public class WialonProtocol extends BaseProtocol { pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 80299ff08..3d57525b7 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; @@ -39,7 +39,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN_ANY = new PatternBuilder() - .expression("([^#]*)?") // imei + .expression("([^#]+)?") // imei .text("#") // start byte .expression("([^#]+)") // type .text("#") // separator @@ -47,13 +47,13 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN = new PatternBuilder() - .number("(dd)(dd)(dd);") // date (ddmmyy) - .number("(dd)(dd)(dd);") // time (hhmmss) + .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) + .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) .number("(?:NA|(dd)(dd.d+));") // latitude .expression("(?:NA|([NS]));") .number("(?:NA|(ddd)(dd.d+));") // longitude .expression("(?:NA|([EW]));") - .number("(d+.?d*)?;") // speed + .number("(?:NA|(d+.?d*))?;") // speed .number("(?:NA|(d+.?d*))?;") // course .number("(?:NA|(-?d+.?d*));") // altitude .number("(?:NA|(d+))") // satellites @@ -95,7 +95,11 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + if (parser.hasNext(6)) { + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + } else { + position.setTime(new Date()); + } if (parser.hasNext(9)) { position.setLatitude(parser.nextCoordinate()); diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index c10ebf505..f7084e55b 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class WliProtocol extends BaseProtocol { - public WliProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WliFrameDecoder()); pipeline.addLast(new WliProtocolDecoder(WliProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index 0e2a0a65e..ec1c4d17a 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,12 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -41,9 +43,9 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header - int type = buf.readUnsignedByte(); + int clazz = buf.readUnsignedByte(); - if (type == '1') { + if (clazz == '1') { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -53,11 +55,13 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + CellTower cellTower = new CellTower(); + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); buf.readUnsignedShort(); // length buf.readUnsignedShort(); // checksum - buf.readUnsignedByte(); // application message type + int type = buf.readUnsignedByte(); buf.readUnsignedByte(); // delimiter while (buf.readableBytes() > 1) { @@ -95,18 +99,56 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { String value = buf.readCharSequence( endIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString(); - switch (fieldNumber) { - case 246: - String[] values = value.split(","); - position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); - position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + int networkFieldsOffset; + switch (type) { + case 0xE4: + networkFieldsOffset = 10; + break; + case 0xCB: + networkFieldsOffset = 80; break; - case 255: - position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + case 0x1E: + networkFieldsOffset = 182; break; + case 0xC9: default: + networkFieldsOffset = 35; break; } + if (fieldNumber - networkFieldsOffset >= 0 && fieldNumber - networkFieldsOffset < 10) { + switch (fieldNumber - networkFieldsOffset) { + case 0: + cellTower.setMobileCountryCode(Integer.parseInt(value)); + break; + case 1: + cellTower.setMobileNetworkCode(Integer.parseInt(value)); + break; + case 2: + cellTower.setLocationAreaCode(Integer.parseInt(value)); + break; + case 3: + cellTower.setCellId(Long.parseLong(value)); + break; + case 4: + cellTower.setSignalStrength(Integer.parseInt(value)); + break; + default: + break; + } + } else { + switch (fieldNumber) { + case 246: + String[] values = value.split(","); + position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + break; + case 255: + position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + break; + default: + break; + } + } } @@ -114,13 +156,21 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { } + if (type == 0xE4) { + getLastLocation(position, position.getDeviceTime()); + } + + if (cellTower.getCellId() != null) { + position.setNetwork(new Network(cellTower)); + } + if (!position.getValid()) { getLastLocation(position, position.getDeviceTime()); } return position; - } else if (type == '2') { + } else if (clazz == '2') { String id = buf.toString(buf.readerIndex(), buf.readableBytes() - 1, StandardCharsets.US_ASCII); getDeviceSession(channel, remoteAddress, id.substring("wli:".length())); diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index 6401fde85..5a0401df4 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -15,16 +15,19 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; +import javax.inject.Inject; public class WondexProtocol extends BaseProtocol { - public WondexProtocol() { + @Inject + public WondexProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_GET_MODEM_STATUS, @@ -40,18 +43,18 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_GET_VERSION, Command.TYPE_IDENTIFICATION); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WondexFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java index b85ae2656..46aa65a5d 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -74,6 +74,9 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -89,12 +92,12 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(parser.nextDateTime()); diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java index 21f1ee321..fb213dc40 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index 1e5ef2c01..c5d8d4050 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -19,13 +19,17 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class WristbandProtocol extends BaseProtocol { - public WristbandProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WristbandProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); pipeline.addLast(new WristbandProtocolDecoder(WristbandProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java index 58b5784d0..323992ddd 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java new file mode 100644 index 000000000..52d43c36c --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class Xexun2FrameEncoder extends MessageToByteEncoder<ByteBuf> { + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { + out.writeBytes(msg.readBytes(2)); + + while (msg.readableBytes() > 2) { + int b = msg.readUnsignedByte(); + if (b == 0xfa && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xaf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x01); + } else if (b == 0xfb && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xbf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x02); + } else { + out.writeByte(b); + } + } + + out.writeBytes(msg.readBytes(2)); + + } +} diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 265841c77..52cf731f0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -18,15 +18,27 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; +import org.traccar.model.Command; + +import javax.inject.Inject; public class Xexun2Protocol extends BaseProtocol { - public Xexun2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xexun2Protocol(Config config) { + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_POWER_OFF, + Command.TYPE_REBOOT_DEVICE); + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Xexun2FrameEncoder()); pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); + pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 766a3f05b..913dfaf28 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -20,10 +20,11 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -41,13 +42,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; public static final int MSG_POSITION = 0x14; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(FLAG); response.writeShort(type); response.writeShort(index); @@ -56,8 +58,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -67,6 +68,9 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(value, 0)) { return Position.ALARM_SOS; } + if (BitUtil.check(value, 1)) { + return Position.ALARM_REMOVING; + } if (BitUtil.check(value, 15)) { return Position.ALARM_FALL_DOWN; } @@ -96,10 +100,16 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - sendResponse(channel, type, index, imei); + int payloadSize = buf.readUnsignedShort() & 0x03ff; + int checksum = buf.readUnsignedShort(); + + if (checksum != Checksum.ip(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + return null; + } - buf.readUnsignedShort(); // attributes - buf.readUnsignedShort(); // checksum + if (type != MSG_COMMAND) { + sendResponse(channel, type, index, imei); + } if (type == MSG_POSITION) { List<Integer> lengths = new ArrayList<>(); @@ -173,7 +183,25 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); - + } + if (BitUtil.check(positionMask, 7)) { + int dataLength = buf.readUnsignedShort(); + if (dataLength > 0) { + int dataType = buf.readUnsignedByte(); + int dataEndIndex = buf.readerIndex() + buf.readUnsignedShort(); + if (dataType == 'G') { + position.setFixTime(position.getDeviceTime()); + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte() > 0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.readUnsignedByte(); // satellite signal-to-noise ratio + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); + } + buf.readerIndex(dataEndIndex); + } } } if (BitUtil.check(mask, 3)) { diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java new file mode 100644 index 000000000..8f3fa5672 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -0,0 +1,70 @@ +/* + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Checksum; +import org.traccar.helper.DataConverter; +import org.traccar.model.Command; +import org.traccar.Protocol; + +import java.nio.charset.StandardCharsets; + +public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { + + public Xexun2ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private static ByteBuf encodeContent(String uniqueId, String content) { + ByteBuf buf = Unpooled.buffer(); + + ByteBuf message = Unpooled.copiedBuffer(content.getBytes(StandardCharsets.US_ASCII)); + + buf.writeShort(Xexun2ProtocolDecoder.FLAG); + buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); + buf.writeShort(1); // index + buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); + buf.writeShort(message.readableBytes()); + buf.writeShort(Checksum.ip(message.nioBuffer())); + buf.writeBytes(message); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + String uniqueId = getUniqueId(command.getDeviceId()); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC: + return encodeContent(uniqueId, + String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POWER_OFF: + return encodeContent(uniqueId, "of=1"); + case Command.TYPE_REBOOT_DEVICE: + return encodeContent(uniqueId, "reset"); + default: + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index b83c4e445..5c7329603 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -15,27 +15,29 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; +import javax.inject.Inject; public class XexunProtocol extends BaseProtocol { - public XexunProtocol() { + @Inject + public XexunProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - boolean full = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + boolean full = config.getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); if (full) { pipeline.addLast(new LineBasedFrameDecoder(1024)); // tracker bug \n\r } else { diff --git a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java index 73d386477..e41d467d5 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index 1be5b6c4b..0841d86d5 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -15,23 +15,26 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; +import javax.inject.Inject; public class XirgoProtocol extends BaseProtocol { - public XirgoProtocol() { + @Inject + public XirgoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -39,9 +42,9 @@ public class XirgoProtocol extends BaseProtocol { pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index 630fe5aed..220c28054 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -18,8 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.nio.NioDatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -40,7 +39,11 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { public XirgoProtocolDecoder(Protocol protocol) { super(protocol); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); } public void setForm(String form) { diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 5d8af418b..65c2a1230 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -21,22 +21,26 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class Xrb28Protocol extends BaseProtocol { - public Xrb28Protocol() { + @Inject + public Xrb28Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1)); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java index 69e5b7372..88f2d07e5 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index ebb3c123f..9e9087609 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -15,20 +15,23 @@ */ 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; +import org.traccar.config.Config; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; +import javax.inject.Inject; public class Xt013Protocol extends BaseProtocol { - public Xt013Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xt013Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java index f49fb9563..ab0b2cdaa 100644 --- a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index 9427876c8..e200adb9f 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -18,13 +18,17 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class Xt2400Protocol extends BaseProtocol { - public Xt2400Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Xt2400Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index 85e8e140f..edcb3f535 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -18,8 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; @@ -38,8 +37,11 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { public Xt2400ProtocolDecoder(Protocol protocol) { super(protocol); + } - String config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + @Override + protected void init() { + String config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); if (config != null) { setConfig(config); } diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index c525b75cf..fb44e2360 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -21,13 +21,17 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; public class YwtProtocol extends BaseProtocol { - public YwtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public YwtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java index bf5a23fa7..fd050bee9 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; |