diff options
18 files changed, 425 insertions, 200 deletions
diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index b8d2b122c..436ef9b02 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.socket.DatagramChannel; +import org.jboss.netty.handler.codec.http.HttpRequestDecoder; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.Position; @@ -103,7 +104,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - if (Context.getConfig().getBoolean("decoder.ignoreSessionCache")) { + if (channel != null && channel.getPipeline().get(HttpRequestDecoder.class) != null + || Context.getConfig().getBoolean("decoder.ignoreSessionCache")) { long deviceId = findDeviceId(remoteAddress, uniqueIds); if (deviceId != 0) { if (Context.getConnectionManager() != null) { diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index a6b3ef964..6cf7a6219 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -46,30 +46,36 @@ public class DeviceResource extends BaseResource { @GET public Collection<Device> get( @QueryParam("all") boolean all, @QueryParam("userId") long userId, + @QueryParam("uniqueId") List<String> uniqueIds, @QueryParam("id") List<Long> deviceIds) throws SQLException { - if (deviceIds.isEmpty()) { - if (all) { - if (Context.getPermissionsManager().isAdmin(getUserId())) { - return Context.getDeviceManager().getAllDevices(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - return Context.getDeviceManager().getManagedDevices(getUserId()); - } + if (all) { + if (Context.getPermissionsManager().isAdmin(getUserId())) { + return Context.getDeviceManager().getAllDevices(); } else { - if (userId == 0) { - userId = getUserId(); - } - Context.getPermissionsManager().checkUser(getUserId(), userId); - return Context.getDeviceManager().getDevices(userId); + Context.getPermissionsManager().checkManager(getUserId()); + return Context.getDeviceManager().getManagedDevices(getUserId()); } - } else { - ArrayList<Device> devices = new ArrayList<>(); - for (Long deviceId : deviceIds) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - devices.add(Context.getDeviceManager().getDeviceById(deviceId)); + } + if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { + if (userId == 0) { + userId = getUserId(); } - return devices; + Context.getPermissionsManager().checkUser(getUserId(), userId); + return Context.getDeviceManager().getDevices(userId); + } + + ArrayList<Device> devices = new ArrayList<>(); + + for (String uniqueId : uniqueIds) { + Device device = Context.getDeviceManager().getDeviceByUniqueId(uniqueId); + Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); + devices.add(device); + } + for (Long deviceId : deviceIds) { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + devices.add(Context.getDeviceManager().getDeviceById(deviceId)); } + return devices; } @POST diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 9e7bac932..4412b012c 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -111,6 +111,7 @@ public class Position extends Message { public static final String ALARM_TOW = "tow"; public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BREAKING = "hardBreaking"; + public static final String ALARM_CORNERING = "hardCornering"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; public static final String ALARM_POWER_RESTORED = "powerRestored"; diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 6f63d0c17..ef02cda7e 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -352,15 +352,28 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim()); } + if ((selector & 0x2000) != 0) { + buf.readUnsignedByte(); // card 1 type + buf.readUnsignedByte(); // card 1 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card1", card); + } + } + + if ((selector & 0x4000) != 0) { + buf.readUnsignedByte(); // card 2 type + buf.readUnsignedByte(); // card 2 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card2", card); + } + } + if ((selector & 0x10000) != 0) { int count = buf.readUnsignedByte(); for (int i = 1; i <= count; i++) { - ChannelBuffer driver = buf.readBytes(22); - int endIndex = driver.indexOf(0, driver.writerIndex(), (byte) 0); - if (endIndex < 0) { - endIndex = driver.writerIndex(); - } - position.set("driver" + i, driver.toString(0, endIndex, StandardCharsets.US_ASCII).trim()); + position.set("driver" + i, buf.readBytes(22).toString(StandardCharsets.US_ASCII).trim()); position.set("driverTime" + i, buf.readUnsignedInt()); } } diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 83664fa5a..3a0ccea78 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -440,7 +440,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } - } else if (version == 4) { + } else if (version == 3 || version == 4) { return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index cb0417528..a7ecf40d5 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -27,6 +27,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { @@ -34,70 +35,157 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Date decodeTime(ChannelBuffer buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return dateBuilder.getDate(); + } - ChannelBuffer buf = (ChannelBuffer) msg; + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { - String header = buf.readBytes(4).toString(StandardCharsets.US_ASCII); + Position position = new Position(); + position.setProtocol(getProtocolName()); - if (header.equals("+EVT")) { + buf.readUnsignedByte(); // message type + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - Position position = new Position(); - position.setProtocol(getProtocolName()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - buf.readUnsignedByte(); // message type + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedInt(); // mask + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version + buf.readUnsignedByte(); // motion status - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + position.setTime(decodeTime(buf)); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + return position; + } + + public static final int MSG_INF_GPS = 2; + public static final int MSG_INF_CID = 4; + public static final int MSG_INF_CSQ = 5; + public static final int MSG_INF_VER = 6; + public static final int MSG_INF_BAT = 7; + public static final int MSG_INF_TMZ = 9; + public static final int MSG_INF_GIR = 10; + + private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + int type = buf.readUnsignedByte(); + + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // motion status + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - int hdop = buf.readUnsignedByte(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); + if (type == MSG_INF_VER) { + buf.readUnsignedShort(); // hardware version + buf.readUnsignedShort(); // mcu version + buf.readUnsignedShort(); // reserved + } - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readShort()); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); + buf.readUnsignedByte(); // motion status + buf.readUnsignedByte(); // reserved + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // mode + buf.skipBytes(7); // last fix time + buf.readUnsignedByte(); // reserved + buf.readUnsignedByte(); + buf.readUnsignedShort(); // response report mask + buf.readUnsignedShort(); // ign interval + buf.readUnsignedShort(); // igf interval + buf.readUnsignedInt(); // reserved + buf.readUnsignedByte(); // reserved + + if (type == MSG_INF_BAT) { + position.set(Position.KEY_CHARGE, buf.readUnsignedByte() != 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); + buf.skipBytes(10); // iccid + if (type == MSG_INF_CSQ) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + buf.readUnsignedByte(); + } + + buf.readUnsignedByte(); // time zone flags + buf.readUnsignedShort(); // time zone offset + + if (type == MSG_INF_GIR) { + buf.readUnsignedByte(); // gir trigger + buf.readUnsignedByte(); // cell number position.setNetwork(new Network(CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort()))); + buf.readUnsignedByte(); // ta + buf.readUnsignedByte(); // rx level + } - buf.readUnsignedByte(); // reserved + getLastLocation(position, decodeTime(buf)); - return position; + return position; + } - } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - return null; + ChannelBuffer buf = (ChannelBuffer) msg; + + switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + case "+INF": + return decodeInformation(channel, remoteAddress, buf); + case "+EVT": + return decodeEvent(channel, remoteAddress, buf); + default: + return null; + } } } diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index a9a72b110..099047aa0 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -248,6 +248,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, alarm.substring(2)); } else if (alarm.startsWith("oil ")) { position.set("oil", alarm.substring(4)); + } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { + position.set(Position.KEY_EVENT, alarm); } DateBuilder dateBuilder = new DateBuilder() diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 24bedcabf..36358b6e5 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -31,6 +31,7 @@ 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; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; @@ -68,6 +69,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; + public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_PHONE = 0x17; public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; @@ -336,7 +338,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); buf.readUnsignedShort(); // type - // Timezone offset if (dataLength > 10) { int extensionBits = buf.readUnsignedShort(); int hours = (extensionBits >> 4) / 100; @@ -391,77 +392,98 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else { - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); + return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - if (type == MSG_LBS_EXTEND) { + } - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return null; + } - getLastLocation(position, dateBuilder.getDate()); + private Object decodeBasicOther(Channel channel, ChannelBuffer buf, + DeviceSession deviceSession, int type, int dataLength) throws Exception { - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - Network network = new Network(); - for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); - } - position.setNetwork(network); + if (type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { - } else if (type == MSG_STRING) { + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - getLastLocation(position, null); + getLastLocation(position, dateBuilder.getDate()); - int commandLength = buf.readUnsignedByte(); + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + Network network = new Network(); + for (int i = 0; i < 7; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); + } - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set(Position.KEY_RESULT, - buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } + buf.readUnsignedByte(); // time leads - } else if (isSupported(type)) { + int wifiCount = buf.readUnsignedByte(); + for (int i = 0; i < wifiCount; i++) { + String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } - if (hasGps(type)) { - decodeGps(position, buf, false); - } else { - getLastLocation(position, null); - } + position.setNetwork(network); - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } + } else if (type == MSG_STRING) { - if (hasStatus(type)) { - decodeStatus(position, buf); - } + getLastLocation(position, null); - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + int commandLength = buf.readUnsignedByte(); + if (commandLength > 0) { + buf.readUnsignedByte(); // server flag (reserved) + position.set(Position.KEY_RESULT, + buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); + } + + } else if (isSupported(type)) { + + if (hasGps(type)) { + decodeGps(position, buf, false); } else { + getLastLocation(position, null); + } - buf.skipBytes(dataLength); - if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, false, type); - } - return null; + if (hasLbs(type)) { + decodeLbs(position, buf, hasStatus(type)); + } + if (hasStatus(type)) { + decodeStatus(position, buf); } - sendResponse(channel, false, type); + if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } - return position; + if (type == MSG_GPS_LBS_2 && 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); + } + + } else { + + buf.skipBytes(dataLength); + if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { + sendResponse(channel, false, type); + } + return null; } - return null; + sendResponse(channel, false, type); + + return position; } private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 2bd02d3f1..f76fd8069 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 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. @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -31,6 +32,8 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; import java.util.regex.Pattern; public class Jt600ProtocolDecoder extends BaseProtocolDecoder { @@ -45,10 +48,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes / 60; } - private Position decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + private List<Position> decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { - Position position = new Position(); - position.setProtocol(getProtocolName()); + List<Position> positions = new LinkedList<>(); buf.readByte(); // header @@ -59,97 +61,106 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } - position.setDeviceId(deviceSession.getDeviceId()); if (longFormat) { buf.readUnsignedByte(); // protocol } - int version = buf.readUnsignedByte() >> 4; + int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length - DateBuilder dateBuilder = new DateBuilder() - .setDay(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setYear(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); - double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - - byte flags = buf.readByte(); - position.setValid((flags & 0x1) == 0x1); - if ((flags & 0x2) == 0) { - latitude = -latitude; - } - position.setLatitude(latitude); - if ((flags & 0x4) == 0) { - longitude = -longitude; - } - position.setLongitude(longitude); + while (buf.readableBytes() > 1) { - position.setSpeed(BcdUtil.readInteger(buf, 2)); - position.setCourse(buf.readUnsignedByte() * 2.0); + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - if (longFormat) { + DateBuilder dateBuilder = new DateBuilder() + .setDay(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setYear(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)); + position.setTime(dateBuilder.getDate()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); + double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - buf.readUnsignedInt(); // vehicle id combined + byte flags = buf.readByte(); + position.setValid((flags & 0x1) == 0x1); + if ((flags & 0x2) == 0) { + latitude = -latitude; + } + position.setLatitude(latitude); + if ((flags & 0x4) == 0) { + longitude = -longitude; + } + position.setLongitude(longitude); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + position.setSpeed(BcdUtil.readInteger(buf, 2)); + position.setCourse(buf.readUnsignedByte() * 2.0); - int battery = buf.readUnsignedByte(); - if (battery == 0xff) { - position.set(Position.KEY_CHARGE, true); - } else { - position.set(Position.KEY_BATTERY_LEVEL, battery); - } + if (longFormat) { + + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - position.setNetwork(new Network(cellTower)); + buf.readUnsignedInt(); // vehicle id combined - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_STATUS, buf.readUnsignedShort()); - } else if (version == 1) { + int battery = buf.readUnsignedByte(); + if (battery == 0xff) { + position.set(Position.KEY_CHARGE, true); + } else { + position.set(Position.KEY_BATTERY_LEVEL, battery); + } - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedByte()); + CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + cellTower.setSignalStrength((int) buf.readUnsignedByte()); + position.setNetwork(new Network(cellTower)); - buf.readByte(); // other flags and sensors + } else if (version == 1) { - position.setAltitude(buf.readUnsignedShort()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte()); - int cid = buf.readUnsignedShort(); - int lac = buf.readUnsignedShort(); - int rssi = buf.readUnsignedByte(); + buf.readByte(); // other flags and sensors - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); - cellTower.setSignalStrength(rssi); - position.setNetwork(new Network(cellTower)); - } else { - position.set(Position.KEY_RSSI, rssi); - } + position.setAltitude(buf.readUnsignedShort()); + + int cid = buf.readUnsignedShort(); + int lac = buf.readUnsignedShort(); + int rssi = buf.readUnsignedByte(); + + if (cid != 0 && lac != 0) { + CellTower cellTower = CellTower.fromCidLac(cid, lac); + cellTower.setSignalStrength(rssi); + position.setNetwork(new Network(cellTower)); + } else { + position.set(Position.KEY_RSSI, rssi); + } - } else if (version == 2) { + } else if (version == 2) { - int fuel = buf.readUnsignedByte() << 8; + int fuel = buf.readUnsignedByte() << 8; - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - fuel += buf.readUnsignedByte(); - position.set(Position.KEY_FUEL_LEVEL, fuel); + fuel += buf.readUnsignedByte(); + position.set(Position.KEY_FUEL_LEVEL, fuel); + + } + + positions.add(position); } - return position; + buf.readUnsignedByte(); // index + + return positions; } private static final Pattern PATTERN_W01 = new PatternBuilder() diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 7702a89fb..6edf4a93e 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.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.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.DateUtil; @@ -104,15 +105,38 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(); position.setProtocol(getProtocolName()); + Integer event = null; + if (parser.hasNext(3)) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); position.setTime(getTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0))); } else if (parser.hasNext()) { position.setTime(getTime(parser.nextInt(0))); } if (parser.hasNext()) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); + } + + if (event != null) { + switch (event) { + case 22: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 23: + position.set(Position.KEY_ALARM, Position.ALARM_BREAKING); + break; + case 24: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 26: + case 28: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + position.set(Position.KEY_EVENT, event); + break; + } } if (parser.hasNext(6)) { @@ -150,6 +174,12 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { attributes = sentence.substring(beginIndex, endIndex).split(";"); } + return decodeAttributes(channel, remoteAddress, position, attributes); + } + + private Position decodeAttributes( + Channel channel, SocketAddress remoteAddress, Position position, String[] attributes) { + String uniqueId = null; DeviceSession deviceSession = null; String messageIndex = null; @@ -161,7 +191,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { String key = attribute.substring(0, index).toLowerCase(); String value = attribute.substring(index + 1); switch (key) { - case "id": uniqueId = value; deviceSession = getDeviceSession(channel, remoteAddress, value); @@ -169,23 +198,30 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); } break; - + case "io": + position.set(Position.KEY_IGNITION, BitUtil.check(value.charAt(0) - '0', 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(value.charAt(0) - '0', 1)); + position.set(Position.KEY_OUTPUT, value.charAt(1) - '0'); + position.set(Position.KEY_INPUT, value.charAt(2) - '0'); + break; + case "ix": + position.set(Position.PREFIX_IO + 1, value); + break; + case "ad": + position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); + break; case "sv": position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); break; - case "bl": - position.set(Position.KEY_BATTERY, Integer.parseInt(value)); + position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); break; - case "vo": position.set(Position.KEY_ODOMETER, Long.parseLong(value)); break; - default: position.set(key, value); break; - } } else if (attribute.startsWith("#")) { messageIndex = attribute; diff --git a/swagger.json b/swagger.json index 734e42eab..a82232f02 100644 --- a/swagger.json +++ b/swagger.json @@ -65,6 +65,14 @@ "required" : false, "type" : "integer", "collectionFormat" : "multi" + }, + { + "name" : "uniqueId", + "in" : "query", + "description" : "To fetch one or more devices. Multiple params can be passed like `uniqueId=333331&uniqieId=44442`", + "required" : false, + "type" : "string", + "collectionFormat" : "multi" } ], "responses": { diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 3c71e86b3..2498d94b3 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol());
verifyAttributes(decoder, binary(
+ "45c20144f667c06ff9005d0161ef17000104596da2dc4b10c0c01d99020d6c04004cba7a010d44463030303235333731363238303030000000000000000000000000000000000000000000000000000001010d44463030303235333731363238303030000000000000031c"));
+
+ verifyAttributes(decoder, binary(
"45c20144f667c07287008c01ffff6d01000059368963d0340a0616207d7f4b10c0c019e6000039d7000039d71f40ffff5001574442393036363035533132333435363700014142432d33343520202020202000011231303331373139343039303030303031000000000000000000000000000000000000000000000000000001011231303331373139343039303030303031000000000000005a"));
verifyAttributes(decoder, binary(
diff --git a/test/org/traccar/protocol/CastelProtocolDecoderTest.java b/test/org/traccar/protocol/CastelProtocolDecoderTest.java index bbc5f1f37..6b52373e1 100644 --- a/test/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(new CastelProtocol()); + verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "40408200033231334c323031373030303131370000000000001001000c6759a10d67590a9e1200000000000e3e0000000000020000000e4e791c000004010d0711060515083017086cd1181f000040067d4944442d3231334c2056312e312e3120323031372d30352d3038004944442d3231334c2056312e312e3000000066e30d0a")); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, "404043000432313345503230313630303035383500000000004006a2021d5810031d58ae940400da050000f6040000070000000400076401680000000001001bd20d0a")); diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index 42ccd4690..24830a953 100644 --- a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, binary( + "2b494e4601fd7f0076676231303000000045010202090104020500004100054007e107150b061d0000003f010e02580000000000d0312a1013648935103226313921591f1200000000000302680003189c1ac3001b02680003189c1ac4000d02680003189c1ac5001207e107150b0d3704f658060d0a")); + verifyPosition(decoder, binary( "2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a")); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 0ac51f4b2..3c767c908 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,15 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "7878412c11030b011c1f013604cb8a00b17754cb8a00bef357cb8a00b73f5fcb8900b0e25fcb8900b6655fcb8a00b74960cb8a00b178620701001801eb40393800bbbde10d0a")); + + verifyNotNull(decoder, binary( + "7878412c11030b012629013604cb8a00b17757cb8a00b73f5bcb8a00b7495ecb8900b0e25fcb8a00b1b9620000000000ff0000000000ffff01001801eb40393e00c0e6340d0a")); + + verifyPosition(decoder, binary( + "787822221106160a1016c60278019407c7783800040001940504700046fc01030100065f570d0a")); + verifyAttributes(decoder, binary( "797900143311070609020b00000000a0030046000109e4610d0a")); @@ -146,6 +155,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "787811010123456789012345100B3201000171930D0A")); + verifyNull(decoder, binary( + "78780d1f000000000000000200b196a20d0a")); + } } diff --git a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3b040297d..eb82d8c23 100644 --- a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -11,13 +11,19 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { Jt600ProtocolDecoder decoder = new Jt600ProtocolDecoder(new Jt600Protocol()); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( + "24624090196121001b19071703493631277203074235752f295800005308010000768b0822")); + + verifyPositions(decoder, binary( + "24624090196123019519071703412131285623074214252f10560000130801000076850819071703420631282832074215165f172c0000030801000076850919071703422131282792074216635f222e0000130801000076850919071703423631282808074218261f212a0000130801000076860819071703435131283678074222928f08350000930801000076860919071703440631283003074223174f19500000930801000076870819071703445131279872074224584f07380000930801000076870819071703453631280643074227091f1b220000530801000076880919071703455131281043074228216f0a260000530801000076880819071703460631281229074228988f0c260000530801000076880819071703462131281551074229954f1f220000530801000076880919071703463631281289074230503f114e0000530801000076880819071703465131281186074230884f094f0000530801000076880819071703470631280308074231240f17500000530801000076880619071703472131280358074231636f0b1d0000530801000076890821")); + + verifyPositions(decoder, binary( "2475604055531611002311111600311326144436028210791d016c0000001f070000000020c03c4f6d07d80ccf")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475201509260111002313101503464722331560113555309F00000000002D0500CB206800F064109326381A03")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475605035891613002328091601152806086750106533350c00000000000a000000000000e1ff4f97007f1607")); verifyPosition(decoder, buffer( @@ -50,17 +56,17 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "(3460311327,U06,10,220916,140619,T,9.552495,N,13.658227,W,0.43,0,7,0%,00101001000000,11012,10,0,0,0,126,0,30)")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24311021600111001B16021105591022329862114046227B0598095080012327951435161F"), position("2011-02-16 05:59:10.000", true, 22.54977, -114.07705)); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B171012052831243810120255336425001907190003FD2B91044D1FA0")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B1710120533052438099702553358450004061E0003EE000000000C00")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24608111888821001B09060908045322564025113242329F0598000001003F0000002D00AB")); verifyPosition(decoder, buffer( diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index 2251763cc..e2de26ec0 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); verifyPosition(decoder, text( + ">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<")); + + verifyPosition(decoder, text( + ">REV011958000369+0307185+1016144400000032;IO=200;SV=9;BL=4158;CF=0,0,0;AD=12347;IX=10213040;FF=0,0,0,0;VO=338572;ID=357042063052352<")); + + verifyPosition(decoder, text( ">REV421942237017+1170957-0701880200000032;ID=356612022463055<")); verifyPosition(decoder, text( diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 50e8600cf..a945178a1 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -62,6 +62,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { decoder.setExtended(true); verifyPositions(decoder, false, binary( + "0000000000000158080b0000015d4b4dc07a00d5dbd13eec04324e020e0000120000000000000000000000015d4b4cd5e800d5dbd13eec04324e020e0000120000000000000000000000015d4b4beb8800d5dbd13eec04324e020e0000130000000000000000000000015d4b4b012800d5dbd13eec04324e020e0000120000000000000000000000015d4b4a16c800d5dbd13eec04324e020f0000110000000000000000000000015d4b492c6800d5dbd13eec04324e020f0000110000000000000000000000015d4b48420800d5dbd13eec04324e020f0000120000000000000000000000015d4b4757a800d5dbd13eec04324e020f00000f0000000000000000000000015d4b466d4800d5dbd13eec04324e020f0000100000000000000000000000015d4b4582e800d5dbd13eec04324e020f0000110000000000000000000000015d4b44988800d5dbd13eec04324e020f0000110000000000000000000b0000ec10")); + + verifyPositions(decoder, false, binary( "00000000000003b5080b0000015ab5642a8800d5db1769ec01d70a020a00e3040004000e0501010200030004006000060900100a00010b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab5642e7000d5db178aec01d6d6020a0070040003000e0501010200030004006000060900100a00000b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab567050000d5db1805ec01da3c02060101040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000046f7000000000001cb000000000000000000000000000000000000015ab56708e800d5db1723ec01d9ec020600e5040006000e05010102000300040060000609000f0a00010b0000130000422f1018000502c700000003f7000000000001cb000000000000000000000000000000000000015ab5685cc000d5db20f7ec01d8fa02080033050007000e05010102000300040060000609000f0a00010b0000130000422f0a18000502c700000030f7000000000001cb000000000000000000000000000000000000015ab5693b6800d5db2367ec01d9430211011b040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000027f7000000000001cb000000000000000000000000000000000000015ab569433800d5db1fb2ec01d9310211008b040006000e0501010200030004006000060900110a00000b0000130000422f1318000402c700000009f7000000000001cb000000000000000000000000000000000000015ab56a0e5800d5db22a2ec01da5502100041050007000e05010102000300040060000609000f0a00000b0000130000422f1118000602c70000000ef7000000000001cb000000000000000000000000000000000000015ab56a700000d5db2afcec01ddb2020a0012050008000e05010102000300040060000609000e0a00000b0000130000422f0918000502c700000026f7000000000001cb000000000000000000000000000000000000015ab56a73e800d5db2ad8ec01de65020a014e050008000e05010102000300040060000609000f0a00010b0000130000422f0818000702c700000002f7000000000001cb000000000000000000000000000000000000015ab56a7bb800d5db2971ec01e00e020a013f040008000e0501010200030004006000060900100a00020b0000130000422f0b18000802c700000004f7000000000001cb000000000000000000000000000000000b00007c5f")); } |