diff options
Diffstat (limited to 'src/org/traccar')
37 files changed, 456 insertions, 206 deletions
diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 8748a9be6..e5fa76a47 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -46,7 +46,16 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { try { Context.getDeviceManager().addDevice(device); + Log.info("Automatically registered device " + uniqueId); + + if (defaultGroupId != 0) { + Context.getPermissionsManager().refreshPermissions(); + if (Context.getGeofenceManager() != null) { + Context.getGeofenceManager().refresh(); + } + } + return device.getId(); } catch (SQLException e) { Log.warning(e); diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 6c271c3ed..68558630d 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.ning.http.client.AsyncHttpClient; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.Properties; import org.apache.velocity.app.VelocityEngine; @@ -238,7 +239,7 @@ public final class Context { geocoder = new FactualGeocoder(url, key, cacheSize); break; case "geocodefarm": - geocoder = new GeocodeFarmGeocoder(key, cacheSize); + geocoder = new GeocodeFarmGeocoder(key, language, cacheSize); break; default: geocoder = new GoogleGeocoder(key, language, cacheSize); @@ -288,9 +289,14 @@ public final class Context { velocityProperties.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute"); - String address = config.getString("web.address", InetAddress.getLocalHost().getHostAddress()); - int port = config.getInteger("web.port", 8082); - String webUrl = URIUtil.newURI("http", address, port, "", ""); + String address; + try { + address = config.getString("web.address", InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + + String webUrl = URIUtil.newURI("http", address, config.getInteger("web.port", 8082), "", ""); webUrl = Context.getConfig().getString("web.url", webUrl); velocityProperties.setProperty("web.url", webUrl); diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 0a54cfeca..ec3e67ec4 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -109,8 +109,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filterApproximate(Position position) { - Boolean approximate = position.getBoolean(Position.KEY_APPROXIMATE); - return filterApproximate && approximate != null && approximate; + return filterApproximate && position.getBoolean(Position.KEY_APPROXIMATE); } private boolean filterStatic(Position position) { diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java index 9972bb74d..83bc5de2e 100644 --- a/src/org/traccar/database/QueryBuilder.java +++ b/src/org/traccar/database/QueryBuilder.java @@ -15,6 +15,7 @@ */ package org.traccar.database; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import org.traccar.Context; import org.traccar.helper.Log; @@ -260,7 +261,8 @@ public final class QueryBuilder { Method[] methods = object.getClass().getMethods(); for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 + && !method.isAnnotationPresent(JsonIgnore.class)) { String name = method.getName().substring(3); try { if (method.getReturnType().equals(boolean.class)) { @@ -424,7 +426,8 @@ public final class QueryBuilder { Method[] methods = clazz.getMethods(); for (final Method method : methods) { - if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 + && !method.isAnnotationPresent(JsonIgnore.class)) { final String name = method.getName().substring(3); diff --git a/src/org/traccar/geocoder/GeocodeFarmGeocoder.java b/src/org/traccar/geocoder/GeocodeFarmGeocoder.java index db23aab79..73ff85aa4 100644 --- a/src/org/traccar/geocoder/GeocodeFarmGeocoder.java +++ b/src/org/traccar/geocoder/GeocodeFarmGeocoder.java @@ -19,15 +19,19 @@ import javax.json.JsonObject; public class GeocodeFarmGeocoder extends JsonGeocoder { - private static String formatUrl(String key) { + private static String formatUrl(String key, String language) { String url = "https://www.geocode.farm/v3/json/reverse/"; + url += "?lat=%f&lon=%f&country=us&count=1"; if (key != null) { url += "&key=" + key; } + if (language != null) { + url += "&lang=" + language; + } return url; } - public GeocodeFarmGeocoder(String key, int cacheSize) { - super(formatUrl(key), cacheSize); + public GeocodeFarmGeocoder(String key, String language, int cacheSize) { + super(formatUrl(key, language), cacheSize); } @Override diff --git a/src/org/traccar/geocoder/NominatimGeocoder.java b/src/org/traccar/geocoder/NominatimGeocoder.java index c10a1414e..4f33468fd 100644 --- a/src/org/traccar/geocoder/NominatimGeocoder.java +++ b/src/org/traccar/geocoder/NominatimGeocoder.java @@ -23,6 +23,7 @@ public class NominatimGeocoder extends JsonGeocoder { if (url == null) { url = "http://nominatim.openstreetmap.org/reverse"; } + url += "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"; if (key != null) { url += "&key=" + key; } diff --git a/src/org/traccar/model/Geofence.java b/src/org/traccar/model/Geofence.java index f10ce6862..ffd4876bf 100644 --- a/src/org/traccar/model/Geofence.java +++ b/src/org/traccar/model/Geofence.java @@ -79,6 +79,7 @@ public class Geofence extends Extensible { return geometry; } + @JsonIgnore public void setGeometry(GeofenceGeometry geometry) { area = geometry.toWkt(); this.geometry = geometry; diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 6fe008688..18e7f7f46 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -22,7 +22,9 @@ public class Position extends Message { public static final String KEY_ORIGINAL = "raw"; public static final String KEY_INDEX = "index"; public static final String KEY_HDOP = "hdop"; - public static final String KEY_SATELLITES = "sat"; + public static final String KEY_VDOP = "vdop"; + public static final String KEY_SATELLITES = "sat"; // in use + public static final String KEY_SATELLITES_VISIBLE = "satVisible"; public static final String KEY_RSSI = "rssi"; public static final String KEY_GPS = "gps"; public static final String KEY_EVENT = "event"; @@ -38,7 +40,8 @@ public class Position extends Message { public static final String KEY_FUEL = "fuel"; public static final String KEY_FUEL_CONSUMPTION = "fuelConsumption"; public static final String KEY_RFID = "rfid"; - public static final String KEY_VERSION = "version"; + public static final String KEY_VERSION_FW = "versionFw"; + public static final String KEY_VERSION_HW = "versionHw"; public static final String KEY_TYPE = "type"; public static final String KEY_IGNITION = "ignition"; public static final String KEY_FLAGS = "flags"; @@ -55,6 +58,8 @@ public class Position extends Message { public static final String KEY_ARMED = "armed"; public static final String KEY_ACCURACY = "accuracy"; public static final String KEY_GEOFENCE = "geofence"; + public static final String KEY_ACCELERATION = "acceleration"; + public static final String KEY_DEVICE_TEMP = "deviceTemp"; public static final String KEY_DTCS = "dtcs"; public static final String KEY_OBD_SPEED = "obdSpeed"; @@ -87,7 +92,7 @@ public class Position extends Message { public static final String ALARM_GPS_ANTENNA_CUT = "gpsAntennaCut"; public static final String ALARM_ACCIDENT = "accident"; public static final String ALARM_TOW = "tow"; - public static final String ALARM_ACCELETATION = "hardAcceleration"; + public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BREAKING = "hardBreaking"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java index f990e05c2..182066629 100644 --- a/src/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/org/traccar/protocol/At2000ProtocolDecoder.java @@ -143,7 +143,7 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() + "mV"); buf.readUnsignedShort(); // cid - buf.readUnsignedByte(); // rssi + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); buf.readUnsignedByte(); // current profile position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 8e3cd2089..d80c19706 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -93,7 +93,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); break; case "GQ": - buf.readUnsignedByte(); // rssi + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; case "CE": buf.readUnsignedInt(); // cid diff --git a/src/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/org/traccar/protocol/Avl301ProtocolDecoder.java index c19b96cb9..cc61be91b 100644 --- a/src/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -100,7 +100,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { int gpsLength = buf.readUnsignedByte(); // gps len and sat position.set(Position.KEY_SATELLITES, gpsLength & 0xf); - buf.readUnsignedByte(); // satellites + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); // satellites double latitude = buf.readUnsignedInt() / 600000.0; double longitude = buf.readUnsignedInt() / 600000.0; diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java index 23889a5bd..615115147 100644 --- a/src/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/org/traccar/protocol/CarcellProtocolDecoder.java @@ -118,7 +118,7 @@ public class CarcellProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(1)) { - position.set("accel", parser.nextInt()); + position.set(Position.KEY_ACCELERATION, parser.nextInt()); } Double internalBattery = (parser.nextDouble() + 100d) * 0.0294d; diff --git a/src/org/traccar/protocol/CellocatorProtocol.java b/src/org/traccar/protocol/CellocatorProtocol.java index bfaf03692..7c8510204 100644 --- a/src/org/traccar/protocol/CellocatorProtocol.java +++ b/src/org/traccar/protocol/CellocatorProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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,6 +20,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; +import org.traccar.model.Command; import java.nio.ByteOrder; import java.util.List; @@ -28,6 +29,8 @@ public class CellocatorProtocol extends BaseProtocol { public CellocatorProtocol() { super("cellocator"); + setSupportedCommands( + Command.TYPE_OUTPUT_CONTROL); } @Override @@ -36,6 +39,7 @@ public class CellocatorProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CellocatorFrameDecoder()); + pipeline.addLast("objectEncoder", new CellocatorProtocolEncoder()); pipeline.addLast("objectDecoder", new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }; @@ -45,6 +49,7 @@ public class CellocatorProtocol extends BaseProtocol { server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("objectEncoder", new CellocatorProtocolEncoder()); pipeline.addLast("objectDecoder", new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }; diff --git a/src/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/org/traccar/protocol/CellocatorProtocolDecoder.java index 14325e619..7df8cad8a 100644 --- a/src/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,6 +68,19 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlarm(short reason) { + switch (reason) { + case 70: + return Position.ALARM_SOS; + case 80: + return Position.ALARM_POWER_CUT; + case 81: + return Position.ALARM_LOW_POWER; + default: + return null; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -106,7 +119,8 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { operator += buf.readUnsignedByte(); buf.readUnsignedByte(); // reason data - buf.readUnsignedByte(); // reason + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // mode buf.readUnsignedInt(); // IO diff --git a/src/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/org/traccar/protocol/CellocatorProtocolEncoder.java new file mode 100644 index 000000000..bb143d349 --- /dev/null +++ b/src/org/traccar/protocol/CellocatorProtocolEncoder.java @@ -0,0 +1,72 @@ +/* + * Copyright 2017 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.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +import java.nio.ByteOrder; + +public class CellocatorProtocolEncoder extends BaseProtocolEncoder { + + private ChannelBuffer encodeContent(long deviceId, int command, int data1, int data2) { + + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + buf.writeByte('M'); + buf.writeByte('C'); + buf.writeByte('G'); + buf.writeByte('P'); + buf.writeByte(0); + buf.writeInt(Integer.parseInt(getUniqueId(deviceId))); + buf.writeByte(0); // command numerator + buf.writeInt(0); // authentication code + buf.writeByte(command); + buf.writeByte(command); + buf.writeByte(data1); + buf.writeByte(data1); + buf.writeByte(data2); + buf.writeByte(data2); + buf.writeInt(0); // command specific data + + byte checksum = 0; + for (int i = 4; i < buf.writerIndex(); i++) { + checksum += buf.getByte(i); + } + buf.writeByte(checksum); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_OUTPUT_CONTROL: + int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4 + + command.getInteger(Command.KEY_INDEX); + return encodeContent(command.getDeviceId(), 0x03, data, 0); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/GalileoProtocolDecoder.java b/src/org/traccar/protocol/GalileoProtocolDecoder.java index c9aae8e96..a3f99c674 100644 --- a/src/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2017 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. @@ -39,24 +39,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final int TAG_IMEI = 0x03; - private static final int TAG_DATE = 0x20; - private static final int TAG_COORDINATES = 0x30; - private static final int TAG_SPEED_COURSE = 0x33; - private static final int TAG_ALTITUDE = 0x34; - private static final int TAG_STATUS = 0x40; - private static final int TAG_POWER = 0x41; - private static final int TAG_BATTERY = 0x42; - private static final int TAG_ODOMETER = 0xd4; - private static final int TAG_REFRIGERATOR = 0x5b; - private static final int TAG_PRESSURE = 0x5c; - private static final int TAG_CAN = 0xc1; - private static final int TAG_ADC0 = 0x50; - private static final int TAG_ADC1 = 0x51; - private static final int TAG_ADC2 = 0x52; - private static final int TAG_ADC3 = 0x53; - private static final int TAG_ARRAY = 0xea; - private static final Map<Integer, Integer> TAG_LENGTH_MAP = new HashMap<>(); static { @@ -96,10 +78,8 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { for (int i : l4) { TAG_LENGTH_MAP.put(i, 4); } - TAG_LENGTH_MAP.put(TAG_COORDINATES, 9); - TAG_LENGTH_MAP.put(TAG_IMEI, 15); - TAG_LENGTH_MAP.put(TAG_REFRIGERATOR, 7); // variable length - TAG_LENGTH_MAP.put(TAG_PRESSURE, 68); + TAG_LENGTH_MAP.put(0x5b, 7); // variable length + TAG_LENGTH_MAP.put(0x5c, 68); } private static int getTagLength(int tag) { @@ -149,77 +129,87 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { tags.add(tag); switch (tag) { - - case TAG_IMEI: + case 0x01: + position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); + break; + case 0x02: + position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); + break; + case 0x03: getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); break; - - case TAG_DATE: + case 0x04: + position.set("deviceId", buf.readUnsignedShort()); + break; + case 0x10: + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + break; + case 0x20: position.setTime(new Date(buf.readUnsignedInt() * 1000)); break; - - case TAG_COORDINATES: + case 0x30: hasLocation = true; position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00); position.setLatitude(buf.readInt() / 1000000.0); position.setLongitude(buf.readInt() / 1000000.0); break; - - case TAG_SPEED_COURSE: + case 0x33: position.setSpeed(buf.readUnsignedShort() * 0.0539957); position.setCourse(buf.readUnsignedShort() * 0.1); break; - - case TAG_ALTITUDE: + case 0x34: position.setAltitude(buf.readShort()); break; - - case TAG_STATUS: + case 0x40: position.set(Position.KEY_STATUS, buf.readUnsignedShort()); break; - - case TAG_POWER: + case 0x41: position.set(Position.KEY_POWER, buf.readUnsignedShort()); break; - - case TAG_BATTERY: + case 0x42: position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); break; - - case TAG_ODOMETER: + case 0x43: + position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); + break; + case 0x44: + position.set(Position.KEY_ACCELERATION, buf.readUnsignedInt()); + break; + case 0x45: + position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + break; + case 0x46: + position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + break; + case 0xd4: position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); break; - - case TAG_CAN: + case 0xc1: position.set(Position.KEY_FUEL, buf.readUnsignedByte() * 0.4); position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte() - 40); position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); break; - - case TAG_ADC0: + case 0x50: position.set(Position.PREFIX_ADC + 0, buf.readUnsignedShort()); break; - - case TAG_ADC1: + case 0x51: position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); break; - - case TAG_ADC2: + case 0x52: position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); break; - - case TAG_ADC3: + case 0x53: position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); break; - - case TAG_ARRAY: - buf.skipBytes(buf.readUnsignedByte()); + case 0xe2: + position.set("userData", buf.readUnsignedInt()); + break; + case 0xea: + position.set("userDataArray", ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedByte()))); break; - default: buf.skipBytes(getTagLength(tag)); break; - } } if (hasLocation && position.getFixTime() != null) { diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 59f013313..4103ebba6 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -107,7 +107,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(?:d{1,2})?,") // gps accuracy + .number("(d{1,2})?,") // hdop .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course .number("(-?d{1,5}.d)?,") // altitude @@ -275,6 +275,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}|x{14}),") // imei .any() + .number("(d{1,2})?,") // hdop .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course .number("(-?d{1,5}.d)?,") // altitude @@ -386,8 +387,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set("deviceType", parser.next()); - position.set("firmwareVersion", parser.nextInt(16)); - position.set("hardwareVersion", parser.nextInt(16)); + position.set(Position.KEY_VERSION_FW, parser.nextInt(16)); + position.set(Position.KEY_VERSION_HW, parser.nextInt(16)); DateBuilder dateBuilder = new DateBuilder() .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) @@ -399,6 +400,10 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } private void decodeLocation(Position position, Parser parser) { + int hdop = parser.nextInt(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); position.setCourse(parser.nextDouble()); position.setAltitude(parser.nextDouble()); @@ -451,11 +456,11 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set("dtcsCodes", parser.next()); position.set(Position.KEY_THROTTLE, parser.next()); position.set(Position.KEY_FUEL, parser.next()); - position.set(Position.KEY_OBD_ODOMETER, parser.next()); + position.set(Position.KEY_OBD_ODOMETER, parser.nextInt() * 1000); decodeLocation(position, parser); - position.set(Position.KEY_ODOMETER, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); if (parser.hasNext(6)) { DateBuilder dateBuilder = new DateBuilder() @@ -510,7 +515,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_BATTERY, parser.next()); - position.set(Position.KEY_ODOMETER, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_HOURS, parser.next()); position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); @@ -666,7 +671,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - position.set(Position.KEY_ODOMETER, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_BATTERY, parser.next()); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); @@ -703,12 +708,15 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + int hdop = parser.nextInt(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); position.setCourse(parser.nextDouble()); position.setAltitude(parser.nextDouble()); if (parser.hasNext(2)) { - position.setValid(true); position.setLongitude(parser.nextDouble()); position.setLatitude(parser.nextDouble()); } else { diff --git a/src/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/org/traccar/protocol/GoSafeProtocolDecoder.java index 94d12e989..96f745917 100644 --- a/src/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -64,7 +64,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { .number("(d+);") // course .number("(d+);") // altitude .number("(d+.d+)") // hdop - .number("(?:;d+.d+)?") // vdop + .number(";(d+.d+)").optional() // vdop .expression(",?") .groupEnd() .groupBegin() @@ -154,7 +154,8 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble()); position.setAltitude(parser.nextDouble()); - position.set(Position.KEY_HDOP, parser.next()); + position.set(Position.KEY_HDOP, parser.nextDouble()); + position.set(Position.KEY_VDOP, parser.nextDouble()); if (parser.hasNext(5)) { position.setNetwork(new Network(CellTower.from( diff --git a/src/org/traccar/protocol/H02FrameDecoder.java b/src/org/traccar/protocol/H02FrameDecoder.java index ac3dbcc2e..391fccc87 100644 --- a/src/org/traccar/protocol/H02FrameDecoder.java +++ b/src/org/traccar/protocol/H02FrameDecoder.java @@ -50,7 +50,12 @@ public class H02FrameDecoder extends FrameDecoder { // Return text message int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); if (index != -1) { - return buf.readBytes(index + 1 - buf.readerIndex()); + ChannelBuffer result = buf.readBytes(index + 1 - buf.readerIndex()); + while (buf.readable() + && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) { + buf.readByte(); // skip new line + } + return result; } break; diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index d2d274eeb..a717ddc4d 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -75,7 +75,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); } - position.set(Position.KEY_IGNITION, !BitUtil.check(status, 10)); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 10)); position.set(Position.KEY_STATUS, status); } diff --git a/src/org/traccar/protocol/HaicomProtocolDecoder.java b/src/org/traccar/protocol/HaicomProtocolDecoder.java index 7cd0b37f2..97e980290 100644 --- a/src/org/traccar/protocol/HaicomProtocolDecoder.java +++ b/src/org/traccar/protocol/HaicomProtocolDecoder.java @@ -72,7 +72,7 @@ public class HaicomProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_VERSION, parser.next()); + position.set(Position.KEY_VERSION_FW, parser.next()); DateBuilder dateBuilder = new DateBuilder() .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) diff --git a/src/org/traccar/protocol/IdplProtocol.java b/src/org/traccar/protocol/IdplProtocol.java index a954397cd..f90d3fe7f 100644 --- a/src/org/traccar/protocol/IdplProtocol.java +++ b/src/org/traccar/protocol/IdplProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.traccar.TrackerServer; public class IdplProtocol extends BaseProtocol { public IdplProtocol() { - super("ldpl"); + super("idpl"); } @Override diff --git a/src/org/traccar/protocol/IdplProtocolDecoder.java b/src/org/traccar/protocol/IdplProtocolDecoder.java index 09a3db9bd..719314f28 100644 --- a/src/org/traccar/protocol/IdplProtocolDecoder.java +++ b/src/org/traccar/protocol/IdplProtocolDecoder.java @@ -106,7 +106,7 @@ public class IdplProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OUTPUT, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextInt()); position.set(Position.PREFIX_ADC + 2, parser.nextInt()); - position.set(Position.KEY_VERSION, parser.next()); + position.set(Position.KEY_VERSION_FW, parser.next()); position.set(Position.KEY_ARCHIVE, parser.next().equals("R")); parser.next(); // checksum diff --git a/src/org/traccar/protocol/KhdProtocolDecoder.java b/src/org/traccar/protocol/KhdProtocolDecoder.java index 0c3d8ee51..1c88a8b9d 100644 --- a/src/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/org/traccar/protocol/KhdProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2017 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. @@ -93,24 +93,42 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(BcdUtil.readCoordinate(buf)); position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4))); position.setCourse(BcdUtil.readInteger(buf, 4)); + position.setValid((buf.readUnsignedByte() & 0x80) != 0); - int flags = buf.readUnsignedByte(); - position.setValid((flags & 0x80) != 0); + if (type != MSG_ALARM) { - if (type == MSG_ALARM) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_HDOP, buf.readUnsignedByte()); + position.set(Position.KEY_VDOP, buf.readUnsignedByte()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.skipBytes(2); + buf.skipBytes(5); // other location data - } else { + if (type == MSG_PERIPHERAL) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); + buf.readUnsignedShort(); // data length - buf.skipBytes(4); // status - buf.skipBytes(8); // other + int dataType = buf.readUnsignedByte(); - } + buf.readUnsignedByte(); // content length - // parse extra data + switch (dataType) { + case 0x01: + position.set(Position.KEY_FUEL, + buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); + break; + case 0x02: + position.set(Position.PREFIX_TEMP + 1, + buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); + break; + default: + break; + } + + } + + } return position; diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java index 360df726a..94c67b616 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -34,106 +34,175 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN = new PatternBuilder() - .expression("![A-D],") + private static final Pattern PATTERN_FIX = new PatternBuilder() .number("(d+)/(d+)/(d+),") // date .number("(d+):(d+):(d+),") // time .number("(-?d+.d+),") // latitude .number("(-?d+.d+),") // longitude - .number("(d+.?d*),") // speed + .compile(); + + private static final Pattern PATTERN_STATE = new PatternBuilder() + .number("(d+.?d*),") // speed (km/h) .number("(d+.?d*),") // course - .groupBegin() .number("(x+),") // flags - .number("(-?d+.d+),") // altitude - .number("(d+),") // battery + .number("(-?d+.d+),") // altitude (meters) + .number("(d+),") // battery (percentage) + .compile(); + + private static final Pattern PATTERN_GPS_PRECISION = new PatternBuilder() .number("(d+),") // satellites in use .number("(d+),") // satellites in view - .text("0") - .or() - .any() - .groupEnd() + .number("(d+.?d*)") // hdop + .compile(); + + private static final Pattern PATTERN_A = new PatternBuilder() + .text("!A,") + .expression(PATTERN_FIX.pattern()) + .any() // unknown 3 fields + .compile(); + + private static final Pattern PATTERN_C = new PatternBuilder() + .text("!C,") + .expression(PATTERN_FIX.pattern()) + .expression(PATTERN_STATE.pattern()) + .any() // unknown 3 fields .compile(); + // The !B (buffered data) records are the same as !D (live data) records. + private static final Pattern PATTERN_BD = new PatternBuilder() + .expression("![BD],") + .expression(PATTERN_FIX.pattern()) + .expression(PATTERN_STATE.pattern()) + .expression(PATTERN_GPS_PRECISION.pattern()) + .compile(); + + private void decodeFix(Position position, Parser parser) { + + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + } + + private void decodeFlags(Position position, int flags) { + + position.setValid(BitUtil.check(flags, 0)); + + if (BitUtil.check(flags, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_FAULT); + } + if (BitUtil.check(flags, 6)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + if (BitUtil.check(flags, 7)) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + if (BitUtil.check(flags, 8)) { + position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); + } + if (BitUtil.check(flags, 9) || BitUtil.check(flags, 10) || BitUtil.check(flags, 11)) { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + } + if (BitUtil.check(flags, 12)) { + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + } + if (BitUtil.check(flags, 15) || BitUtil.check(flags, 14)) { + position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + } + + position.set(Position.KEY_RSSI, BitUtil.between(flags, 16, 20)); + position.set(Position.KEY_CHARGE, BitUtil.check(flags, 22)); + } + + private void decodeState(Position position, Parser parser) { + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + + position.setCourse(parser.nextDouble()); + if (position.getCourse() > 360) { + position.setCourse(0); + } + + decodeFlags(position, parser.nextInt(16)); + + position.setAltitude(parser.nextDouble()); + + position.set(Position.KEY_BATTERY, parser.nextInt()); + } + + private void decodeGPSPrecision(Position position, Parser parser) { + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt()); + position.set(Position.KEY_HDOP, parser.nextDouble()); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - if (sentence.startsWith("!1")) { + if (sentence.startsWith("!1,")) { getDeviceSession(channel, remoteAddress, sentence.substring(3, sentence.length())); - } else if (sentence.matches("![A-D].*")) { + return null; + } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + if (!sentence.matches("![A-D],.*")) { + return null; + } - Parser parser = new Parser(PATTERN, sentence); + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + String recordType = sentence.substring(1, 2); + position.set(Position.KEY_TYPE, recordType); + + if (recordType.matches("[BD]")) { + Parser parser = new Parser(PATTERN_BD, sentence); if (!parser.matches()) { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + decodeFix(position, parser); + decodeState(position, parser); + decodeGPSPrecision(position, parser); - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + return position; + } - position.setCourse(parser.nextDouble()); - if (position.getCourse() > 360) { - position.setCourse(0); + if (recordType.matches("C")) { + Parser parser = new Parser(PATTERN_C, sentence); + if (!parser.matches()) { + return null; } - if (parser.hasNext(5)) { - - int flags = parser.nextInt(16); - - position.setValid(BitUtil.check(flags, 0)); - - if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_ALARM, Position.ALARM_FAULT); - } - if (BitUtil.check(flags, 6)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - if (BitUtil.check(flags, 7)) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - if (BitUtil.check(flags, 8)) { - position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); - } - if (BitUtil.check(flags, 9) || BitUtil.check(flags, 10) || BitUtil.check(flags, 11)) { - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - } - if (BitUtil.check(flags, 12)) { - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - } - if (BitUtil.check(flags, 15) || BitUtil.check(flags, 14)) { - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - } - - position.set(Position.KEY_RSSI, BitUtil.between(flags, 16, 20)); - position.set(Position.KEY_CHARGE, BitUtil.check(flags, 22)); - - position.setAltitude(parser.nextDouble()); - - position.set(Position.KEY_BATTERY, parser.next()); - position.set(Position.KEY_SATELLITES, parser.next()); + decodeFix(position, parser); + decodeState(position, parser); + return position; + } + + if (recordType.matches("A")) { + Parser parser = new Parser(PATTERN_A, sentence); + if (!parser.matches()) { + return null; } - return position; + decodeFix(position, parser); + return position; } return null; diff --git a/src/org/traccar/protocol/NavigilProtocolDecoder.java b/src/org/traccar/protocol/NavigilProtocolDecoder.java index d18217861..263e5fc2b 100644 --- a/src/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/org/traccar/protocol/NavigilProtocolDecoder.java @@ -95,8 +95,8 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(buf.readInt() * 0.0000001); position.setAltitude(buf.readUnsignedShort()); - buf.readUnsignedShort(); // satellites in fix - buf.readUnsignedShort(); // satellites in track + position.set(Position.KEY_SATELLITES, buf.readUnsignedShort()); // satellites in fix + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShort()); // satellites in track buf.readUnsignedShort(); // GPS antenna state position.setSpeed(buf.readUnsignedShort() * 0.194384); @@ -107,7 +107,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - buf.readUnsignedShort(); // battery charger status + position.set(Position.KEY_CHARGE, buf.readUnsignedShort()); // battery charger status position.setTime(convertTimestamp(buf.readUnsignedInt())); @@ -133,8 +133,8 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(buf.readInt() * 0.0000001); position.setAltitude(buf.readUnsignedShort()); - buf.readUnsignedByte(); // satellites in fix - buf.readUnsignedByte(); // satellites in track + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // satellites in fix + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); // satellites in track position.setSpeed(buf.readUnsignedShort() * 0.194384); position.setCourse(buf.readUnsignedShort()); @@ -219,8 +219,8 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(buf.readInt() * 0.0000001); position.setAltitude(buf.readUnsignedShort()); - buf.readUnsignedByte(); // satellites in fix - buf.readUnsignedByte(); // satellites in track + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // satellites in fix + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); // satellites in track position.setSpeed(buf.readUnsignedShort() * 0.194384); position.setCourse(buf.readUnsignedShort() * 0.1); @@ -258,7 +258,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); position.setCourse(buf.readUnsignedByte() * 2.0); - buf.readUnsignedByte(); // satellites in fix + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // satellites in fix position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java index d10f754e9..9538053b6 100644 --- a/src/org/traccar/protocol/OigoProtocolDecoder.java +++ b/src/org/traccar/protocol/OigoProtocolDecoder.java @@ -208,7 +208,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { int index = buf.readUnsignedByte(); - position.set(Position.KEY_VERSION, buf.readUnsignedByte()); + position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_ODOMETER, (long) (buf.readUnsignedInt() * 1609.34)); diff --git a/src/org/traccar/protocol/PricolProtocol.java b/src/org/traccar/protocol/PricolProtocol.java index 924c7c1d6..0005dc3c1 100644 --- a/src/org/traccar/protocol/PricolProtocol.java +++ b/src/org/traccar/protocol/PricolProtocol.java @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder; @@ -38,6 +39,12 @@ public class PricolProtocol extends BaseProtocol { pipeline.addLast("objectDecoder", new PricolProtocolDecoder(PricolProtocol.this)); } }); + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("objectDecoder", new PricolProtocolDecoder(PricolProtocol.this)); + } + }); } } diff --git a/src/org/traccar/protocol/PricolProtocolDecoder.java b/src/org/traccar/protocol/PricolProtocolDecoder.java index 52b68cca6..3313afa22 100644 --- a/src/org/traccar/protocol/PricolProtocolDecoder.java +++ b/src/org/traccar/protocol/PricolProtocolDecoder.java @@ -87,7 +87,7 @@ public class PricolProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, buf.readUnsignedShort()); if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer("ACK", StandardCharsets.US_ASCII)); + channel.write(ChannelBuffers.copiedBuffer("ACK", StandardCharsets.US_ASCII), remoteAddress); } return position; diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java index 54f54d392..a72d237d3 100644 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -65,7 +65,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { case "TOW":
return Position.ALARM_TOW;
case "HDA":
- return Position.ALARM_ACCELETATION;
+ return Position.ALARM_ACCELERATION;
case "HDB":
return Position.ALARM_BREAKING;
case "FDA":
diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java index fa789510e..87e55ea86 100644 --- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -112,7 +112,7 @@ public class Stl060ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextInt()); position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); position.set(Position.KEY_FUEL, parser.nextInt()); - position.set("accel", parser.nextInt() == 1); + position.set(Position.KEY_ACCELERATION, parser.nextInt() == 1); position.set(Position.KEY_OUTPUT, parser.nextInt() + parser.nextInt() << 1); } diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index d081cb901..55d5c224a 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -65,7 +65,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_VERSION, values[index++]); + position.set(Position.KEY_VERSION_FW, values[index++]); DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); @@ -116,7 +116,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { index += 1; // model } - position.set(Position.KEY_VERSION, values[index++]); + position.set(Position.KEY_VERSION_FW, values[index++]); DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 7927c28e6..c53538223 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2017 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. @@ -48,7 +48,8 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .groupEnd("?") .number("(d{5})") // seconds .or() - .text("RGP") // type + .expression("(?:RGP|RCQ|RBR)") // type + .number("(?:dd)?") .number("(dd)(dd)(dd)") // date .number("(dd)(dd)(dd)") // time .groupEnd() @@ -56,6 +57,13 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .number("([-+]ddd)(d{5})") // longitude .number("(ddd)") // speed .number("(ddd)") // course + .groupBegin() + .number("(xx)") // input + .number("(xx)") // satellites + .number("(ddd)") // battery + .number("(x{8})") // odometer + .number("[01]") // gps power + .groupEnd("?") .number("(d)") // fix mode .any() .compile(); @@ -93,15 +101,10 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(); position.setProtocol(getProtocolName()); - String week = parser.next(); - String day = parser.next(); - String seconds = parser.next(); - if (seconds != null) { - if (week != null && day != null) { - position.setTime(getTime(Integer.parseInt(week), Integer.parseInt(day), Integer.parseInt(seconds))); - } else { - position.setTime(getTime(Integer.parseInt(seconds))); - } + if (parser.hasNext(2)) { + position.setTime(getTime(parser.nextInt(), parser.nextInt(), parser.nextInt())); + } else if (parser.hasNext()) { + position.setTime(getTime(parser.nextInt())); } if (parser.hasNext(6)) { @@ -115,6 +118,14 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG)); position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble())); position.setCourse(parser.nextDouble()); + + if (parser.hasNext(4)) { + position.set(Position.KEY_INPUT, parser.nextInt(16)); + position.set(Position.KEY_SATELLITES, parser.nextInt(16)); + position.set(Position.KEY_BATTERY, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextLong(16)); + } + position.setValid(parser.nextInt() != 0); String[] attributes = null; diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4d4d68ec2..203f62f87 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -89,7 +89,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() + "mV"); break; case 70: - position.set("pcbTemp", (length == 4 ? buf.readInt() : buf.readShort()) * 0.1); + position.set(Position.KEY_DEVICE_TEMP, (length == 4 ? buf.readInt() : buf.readShort()) * 0.1); break; case 72: position.set(Position.PREFIX_TEMP + 1, buf.readInt() * 0.1); @@ -171,7 +171,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(locationMask, 6)) { - buf.readUnsignedByte(); // rssi + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } if (BitUtil.check(locationMask, 7)) { diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java index beb2b0b78..40ce04c5b 100644 --- a/src/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/org/traccar/protocol/TmgProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -50,16 +51,21 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder { .number("(-?d+.?d*),") // altitude .number("(d+.d+),") // hdop .number("(d+),") // satellites - .number("d+,") // visible satellites - .number("[^,]*,") // operator - .number("d+,") // rssi - .number("[^,]*,") // cid + .number("(d+),") // visible satellites + .number("([^,]*),") // operator + .number("(d+),") // rssi + .number("[^,]*,") // cid .expression("([01]),") // ignition .number("(d+.?d*),") // battery .number("(d+.?d*),") // power .expression("([01]+),") // input .expression("([01]+),") // output .expression("[01]+,") // temper status + .number("(d+.?d*)[^,]*,") // adc1 + .number("(d+.?d*)[^,]*,") // adc2 + .number("d+.?d*,") // trip meter + .expression("([^,]*),") // software version + .expression("([^,]*),").optional() // rfid .any() .compile(); @@ -122,11 +128,27 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HDOP, parser.nextDouble()); position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt()); + position.set("operator", parser.next()); + position.set(Position.KEY_RSSI, parser.nextInt()); position.set(Position.KEY_IGNITION, parser.nextInt() == 1); position.set(Position.KEY_BATTERY, parser.nextDouble()); position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_INPUT, parser.nextInt(2)); - position.set(Position.KEY_OUTPUT, parser.nextInt(2)); + + int input = parser.nextInt(2); + int output = parser.nextInt(2); + + if (!BitUtil.check(input, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, output); + + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); + position.set(Position.KEY_VERSION_FW, parser.next()); + position.set(Position.KEY_RFID, parser.next()); return position; } diff --git a/src/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/org/traccar/protocol/TrakMateProtocolDecoder.java index 57003e832..d1bd1398b 100644 --- a/src/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -125,7 +125,7 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder { .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); - position.set(Position.KEY_VERSION, parser.next()); + position.set(Position.KEY_VERSION_FW, parser.next()); parser.next(); // hardware version return position; diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index 2b5d90e7a..0fc93a03c 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java @@ -45,7 +45,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { case 0x14: return Position.ALARM_BREAKING; case 0x15: - return Position.ALARM_ACCELETATION; + return Position.ALARM_ACCELERATION; case 0x30: return Position.ALARM_PARKING; case 0x42: |