diff options
Diffstat (limited to 'src/main/java/org/traccar')
9 files changed, 379 insertions, 10 deletions
diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 6596d8764..283dbeb37 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -119,9 +119,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2})?,") // hdop + .number("(d{1,2}.?d?)?,") // hdop .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course + .number("(d{1,3}.?d?)?,") // course .number("(-?d{1,5}.d)?,") // altitude .number("(-?d{1,3}.d{6})?,") // longitude .number("(-?d{1,2}.d{6})?,") // latitude @@ -184,7 +184,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(d+)?,") // power .number("d{1,2},").optional() // report type .number("d{1,2},").optional() // count - .number(",").optional() // reserved + .number("d*,").optional() // reserved .number("(d+),").optional() // battery .expression("((?:") .expression(PATTERN_LOCATION.pattern()) @@ -202,6 +202,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .or() .number("(d{1,7}.d)?,").optional() // odometer .number("(d{1,3})?,") // battery + .or() + .number("(-?d),") // rssi + .number("(d{1,3}),") // battery .groupEnd() .any() .number("(dddd)(dd)(dd)") // date (yyyymmdd) @@ -514,7 +517,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private void decodeLocation(Position position, Parser parser) { - Integer hdop = parser.nextInt(); + Double hdop = parser.nextDouble(); position.setValid(hdop == null || hdop > 0); position.set(Position.KEY_HDOP, hdop); @@ -848,6 +851,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { 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) { diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index ebc7e7c04..c97017d65 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -163,6 +163,18 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { position.set("tagData", values[index++]); break; case "IWD": + while (index < values.length) { + index += 1; // data identifier + int dataType = Integer.parseInt(values[index++]); + if (dataType == 0) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index++]); + } else if (dataType == 1) { + index += 1; // temperature sensor serial number + position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(values[index++])); + + } + } + if (index < values.length && values[index + 1].equals("0")) { position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index + 2]); } diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java new file mode 100644 index 000000000..05f63a2d7 --- /dev/null +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 Jesse Hills (jesserockz@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class LeafSpyProtocol extends BaseProtocol { + + public LeafSpyProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(16384)); + pipeline.addLast(new LeafSpyProtocolDecoder(LeafSpyProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java new file mode 100644 index 000000000..5b352a961 --- /dev/null +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -0,0 +1,139 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 Jesse Hills (jesserockz@gmail.com) + * + * 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.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.model.Position; +import org.traccar.NetworkMessage; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class LeafSpyProtocolDecoder extends BaseHttpProtocolDecoder { + + public LeafSpyProtocolDecoder(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.uri()); + Map<String, List<String>> params = decoder.parameters(); + if (params.isEmpty()) { + decoder = new QueryStringDecoder(request.content().toString(StandardCharsets.US_ASCII), false); + params = decoder.parameters(); + } + + Position position = new Position(getProtocolName()); + position.setValid(true); + + for (Map.Entry<String, List<String>> entry : params.entrySet()) { + for (String value : entry.getValue()) { + switch (entry.getKey()) { + case "pass": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + break; + case "Lat": + position.setLatitude(Double.parseDouble(value)); + break; + case "Long": + position.setLongitude(Double.parseDouble(value)); + break; + case "RPM": + position.set(Position.KEY_RPM, Integer.parseInt(value)); + position.setSpeed(convertSpeed(Double.parseDouble(value) / 63, "kmh")); + break; + case "Elv": + position.setAltitude(Double.parseDouble(value)); + break; + case "SOC": + position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); + break; + case "user": + position.set(Position.KEY_DRIVER_UNIQUE_ID, value); + break; + case "ChrgMode": + position.set(Position.KEY_CHARGE, Integer.parseInt(value) != 0); + break; + case "Odo": + position.set(Position.KEY_OBD_ODOMETER, Integer.parseInt(value) * 1000); + break; + default: + try { + position.set(entry.getKey(), Double.parseDouble(value)); + } catch (NumberFormatException e) { + switch (value) { + case "true": + position.set(entry.getKey(), true); + break; + case "false": + position.set(entry.getKey(), false); + break; + default: + position.set(entry.getKey(), value); + break; + } + } + break; + } + } + } + + if (position.getFixTime() == null) { + position.setTime(new Date()); + } + + if (position.getLatitude() == 0 && position.getLongitude() == 0) { + getLastLocation(position, position.getDeviceTime()); + } + + if (position.getDeviceId() != 0) { + if (channel != null) { + HttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, + HttpResponseStatus.OK, + Unpooled.copiedBuffer("\"status\":\"0\"", StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + return position; + } else { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index e83318fa9..7204769b2 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -117,7 +117,9 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); + int event = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001); } @@ -131,7 +133,9 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { index += 4; // fix values - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); + int event = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001); } diff --git a/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java new file mode 100644 index 000000000..e5e13b305 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.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.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BitUtil; + +public class NavisetFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int length = 2 + BitUtil.to(buf.getUnsignedShortLE(buf.readerIndex()), 12) + 2; + + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java new file mode 100644 index 000000000..78755ea4d --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -0,0 +1,34 @@ +/* + * 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 org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class NavisetProtocol extends BaseProtocol { + + public NavisetProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + 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 new file mode 100644 index 000000000..36a060176 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java @@ -0,0 +1,94 @@ +/* + * 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.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class NavisetProtocolDecoder extends BaseProtocolDecoder { + + public NavisetProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_HEADER = 0b00; + public static final int MSG_DATA = 0b01; + public static final int MSG_RESPONSE = 0b10; + public static final int MSG_RESERVE = 0b11; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeByte(0x01); + response.writeShortLE(buf.getUnsignedShortLE(buf.writerIndex() - 2)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + + int length = buf.readUnsignedShortLE(); + BitUtil.between(length, 12, 14); // version + int type = BitUtil.between(length, 14, 16); + buf.readUnsignedShortLE(); // device number + + if (type == MSG_HEADER) { + + getDeviceSession(channel, remoteAddress, buf.readCharSequence(15, StandardCharsets.US_ASCII).toString()); + + } else if (type == MSG_DATA) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // mask + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); + position.set(Position.KEY_STATUS, buf.readUnsignedByte()); + + position.setValid(true); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLatitude(buf.readUnsignedIntLE() * 0.000001); + position.setLongitude(buf.readUnsignedIntLE() * 0.000001); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); + + // additional data + + return position; + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index b63385187..05312b820 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * 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. @@ -42,7 +42,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .expression("[A-Z]{2,3}") - .number("APdd") + .expression("[A-Z]P") + .number("dd") .number("(dd)(dd)(dd)") // date (yymmdd) .expression("([AV])") // validity .number("(dd)(dd.d+)") // latitude @@ -57,7 +58,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)") // battery .number("(d)") // acc .number("(dd)") // arm status - .number("(dd),") // working mode + .number("(dd)") // working mode + .number("(?:[0-2]{3})?,") .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -181,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("AP01") || type.equals("AP10")) { + } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { |