diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2019-12-07 22:32:42 -0800 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2019-12-07 22:32:42 -0800 |
commit | 9a5891a1d2fdca01a04b4f47db375347b504322b (patch) | |
tree | 038430f1c9691fe37bae4a95338c0ad63f08618a | |
parent | 3e402ffca4649a390d237c6aba8678022b23370a (diff) | |
download | trackermap-server-9a5891a1d2fdca01a04b4f47db375347b504322b.tar.gz trackermap-server-9a5891a1d2fdca01a04b4f47db375347b504322b.tar.bz2 trackermap-server-9a5891a1d2fdca01a04b4f47db375347b504322b.zip |
Implement S168 protocol
-rw-r--r-- | setup/default.xml | 1 | ||||
-rw-r--r-- | src/main/java/org/traccar/protocol/S168Protocol.java | 39 | ||||
-rw-r--r-- | src/main/java/org/traccar/protocol/S168ProtocolDecoder.java | 81 | ||||
-rw-r--r-- | src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java | 21 |
4 files changed, 142 insertions, 0 deletions
diff --git a/setup/default.xml b/setup/default.xml index 37a932dc0..090334739 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -280,5 +280,6 @@ <entry key='solarpowered.port'>5201</entry> <entry key='motor.port'>5202</entry> <entry key='omnicomm.port'>5203</entry> + <entry key='s168.port'>5204</entry> </properties> diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java new file mode 100644 index 000000000..e78664c40 --- /dev/null +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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; + +public class S168Protocol extends BaseProtocol { + + public S168Protocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new S168ProtocolDecoder(S168Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java new file mode 100644 index 000000000..71aff1a65 --- /dev/null +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -0,0 +1,81 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class S168ProtocolDecoder extends BaseProtocolDecoder { + + public S168ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + String[] values = sentence.split("#"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[1]); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + String content = values[4]; + String[] fragments = content.split(";"); + for (String fragment : fragments) { + + int dataIndex = fragment.indexOf(':'); + String type = fragment.substring(0, dataIndex); + values = fragment.substring(dataIndex + 1).split(","); + int index = 0; + + switch (type) { + case "GDATA": + position.setValid(values[index++].equals("A")); + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(values[index++])); + position.setLatitude(Double.parseDouble(values[index++])); + position.setLongitude(Double.parseDouble(values[index++])); + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + position.setCourse(Integer.parseInt(values[index++])); + position.setAltitude(Integer.parseInt(values[index++])); + break; + default: + break; + } + } + + return position.getAttributes().containsKey(Position.KEY_SATELLITES) ? position : null; + } + +} diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java new file mode 100644 index 000000000..8a4a42b54 --- /dev/null +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class S168ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + S168ProtocolDecoder decoder = new S168ProtocolDecoder(null); + + verifyNull(decoder, text( + "S168#358511139046180#00c9#0009#SYNC:0000")); + + verifyPosition(decoder, text( + "S168#000000000000008#0f12#0077#LOCA:G;CELL:1,1cc,2,2795,1435,64;GDATA:A,12,160412154800,22.564025,113.242329,5.5,152,900;ALERT:0000;STATUS:89,98;WAY:0")); + + } + +} |