diff options
Diffstat (limited to 'src/org/traccar')
-rw-r--r-- | src/org/traccar/BaseHttpProtocolDecoder.java | 39 | ||||
-rw-r--r-- | src/org/traccar/protocol/DmtHttpProtocolDecoder.java | 16 | ||||
-rw-r--r-- | src/org/traccar/protocol/FlespiProtocolDecoder.java | 20 | ||||
-rw-r--r-- | src/org/traccar/protocol/GoSafeProtocolDecoder.java | 16 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gt06ProtocolDecoder.java | 178 | ||||
-rw-r--r-- | src/org/traccar/protocol/Jt600FrameDecoder.java | 4 | ||||
-rw-r--r-- | src/org/traccar/protocol/OsmAndProtocolDecoder.java | 16 | ||||
-rw-r--r-- | src/org/traccar/protocol/OwnTracksProtocolDecoder.java | 25 | ||||
-rw-r--r-- | src/org/traccar/protocol/SigfoxProtocol.java | 47 | ||||
-rw-r--r-- | src/org/traccar/protocol/SigfoxProtocolDecoder.java | 91 | ||||
-rw-r--r-- | src/org/traccar/protocol/StarcomProtocol.java | 45 | ||||
-rw-r--r-- | src/org/traccar/protocol/StarcomProtocolDecoder.java | 121 |
12 files changed, 506 insertions, 112 deletions
diff --git a/src/org/traccar/BaseHttpProtocolDecoder.java b/src/org/traccar/BaseHttpProtocolDecoder.java new file mode 100644 index 000000000..934a1b81e --- /dev/null +++ b/src/org/traccar/BaseHttpProtocolDecoder.java @@ -0,0 +1,39 @@ +/* + * 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; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; +import org.jboss.netty.handler.codec.http.HttpHeaders; +import org.jboss.netty.handler.codec.http.HttpResponse; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.jboss.netty.handler.codec.http.HttpVersion; + +public abstract class BaseHttpProtocolDecoder extends BaseProtocolDecoder { + + public BaseHttpProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public void sendResponse(Channel channel, HttpResponseStatus status) { + if (channel != null) { + HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); + response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 0); + channel.write(response); + } + } + +} diff --git a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java index 1bd808a1f..dbcc7a6f8 100644 --- a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -16,13 +16,9 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; -import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; -import org.traccar.BaseProtocolDecoder; +import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; @@ -40,20 +36,12 @@ import java.util.LinkedList; import java.util.List; import java.util.TimeZone; -public class DmtHttpProtocolDecoder extends BaseProtocolDecoder { +public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { public DmtHttpProtocolDecoder(DmtHttpProtocol protocol) { super(protocol); } - private void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); - response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 0); - channel.write(response); - } - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java index 799d78ecb..d122df383 100644 --- a/src/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java @@ -16,13 +16,9 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; -import org.jboss.netty.handler.codec.http.HttpHeaders; -import org.traccar.BaseProtocolDecoder; +import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.model.Position; @@ -34,11 +30,11 @@ import javax.json.JsonString; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.LinkedList; import java.util.Date; +import java.util.LinkedList; +import java.util.List; -public class FlespiProtocolDecoder extends BaseProtocolDecoder { +public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { public FlespiProtocolDecoder(FlespiProtocol protocol) { super(protocol); @@ -72,14 +68,6 @@ public class FlespiProtocolDecoder extends BaseProtocolDecoder { return positions; } - private void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); - response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 0); - channel.write(response); - } - } - private void decodePosition(JsonObject object, Position position) { position.setProtocol(getProtocolName()); diff --git a/src/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/org/traccar/protocol/GoSafeProtocolDecoder.java index f9aaae0ce..62f6212e2 100644 --- a/src/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -168,10 +168,18 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextDouble()); if (parser.hasNext(6)) { - long status = parser.nextLong(16, 0); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 13)); - position.set(Position.KEY_STATUS, status); - position.set("ioStatus", parser.next()); + position.set(Position.KEY_STATUS, parser.nextHexLong()); + Integer io = parser.nextHexInt(); + if (io != null) { + position.set(Position.KEY_IGNITION, BitUtil.check(io, 0)); + position.set(Position.PREFIX_IN + 1, BitUtil.check(io, 1)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(io, 2)); + position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 3)); + position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 4)); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 5)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 6)); + position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 7)); + } position.set(Position.KEY_GEOFENCE, parser.next() + parser.next()); position.set("eventStatus", parser.next()); position.set("packetType", parser.next()); diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 177c0b653..2018fb6a6 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -36,6 +36,7 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Calendar; import java.util.HashMap; import java.util.Map; import java.util.TimeZone; @@ -78,6 +79,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; public static final int MSG_GPS_LBS_EXTEND = 0x1E; + public static final int MSG_HEARTBEAT = 0x23; + public static final int MSG_ADDRESS_REQUEST = 0x2A; + public static final int MSG_ADDRESS_RESPONSE = 0x97; public static final int MSG_AZ735_GPS = 0x32; public static final int MSG_AZ735_ALARM = 0x33; public static final int MSG_X1_GPS = 0x34; @@ -87,27 +91,69 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; + public static final int MSG_TIME_REQUEST = 0x8A; public static final int MSG_INFO = 0x94; public static final int MSG_STRING_INFO = 0x21; + public static final int MSG_GPS_2 = 0xA0; + public static final int MSG_LBS_2 = 0xA1; + public static final int MSG_WIFI_3 = 0xA2; + public static final int MSG_FENCE_SINGLE = 0xA3; + public static final int MSG_FENCE_MULTI = 0xA4; + public static final int MSG_LBS_ALARM = 0xA5; + public static final int MSG_LBS_ADDRESS = 0xA7; private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); } private static boolean hasGps(int type) { - return type == MSG_GPS || type == MSG_GPS_LBS_1 || type == MSG_GPS_LBS_2 - || type == MSG_GPS_LBS_STATUS_1 || type == MSG_GPS_LBS_STATUS_2 || type == MSG_GPS_LBS_STATUS_3 - || type == MSG_GPS_PHONE || type == MSG_GPS_LBS_EXTEND; + switch (type) { + case MSG_GPS: + case MSG_GPS_LBS_1: + case MSG_GPS_LBS_2: + case MSG_GPS_LBS_STATUS_1: + case MSG_GPS_LBS_STATUS_2: + case MSG_GPS_LBS_STATUS_3: + case MSG_GPS_PHONE: + case MSG_GPS_LBS_EXTEND: + case MSG_GPS_2: + case MSG_FENCE_SINGLE: + return true; + default: + return false; + } } private static boolean hasLbs(int type) { - return type == MSG_LBS || type == MSG_LBS_STATUS || type == MSG_GPS_LBS_1 || type == MSG_GPS_LBS_2 - || type == MSG_GPS_LBS_STATUS_1 || type == MSG_GPS_LBS_STATUS_2 || type == MSG_GPS_LBS_STATUS_3; + switch (type) { + case MSG_LBS: + case MSG_LBS_STATUS: + case MSG_GPS_LBS_1: + case MSG_GPS_LBS_2: + case MSG_GPS_LBS_STATUS_1: + case MSG_GPS_LBS_STATUS_2: + case MSG_GPS_LBS_STATUS_3: + case MSG_GPS_2: + case MSG_FENCE_SINGLE: + case MSG_LBS_ALARM: + case MSG_LBS_ADDRESS: + return true; + default: + return false; + } } private static boolean hasStatus(int type) { - return type == MSG_STATUS || type == MSG_LBS_STATUS - || type == MSG_GPS_LBS_STATUS_1 || type == MSG_GPS_LBS_STATUS_2 || type == MSG_GPS_LBS_STATUS_3; + switch (type) { + case MSG_STATUS: + case MSG_LBS_STATUS: + case MSG_GPS_LBS_STATUS_1: + case MSG_GPS_LBS_STATUS_2: + case MSG_GPS_LBS_STATUS_3: + return true; + default: + return false; + } } private void sendResponse(Channel channel, boolean extended, int type, ChannelBuffer content) { @@ -348,6 +394,44 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, false, type, null); } + } else if (type == MSG_HEARTBEAT) { + + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); + + getLastLocation(position, null); + + int status = buf.readUnsignedByte(); + position.set(Position.KEY_ARMED, BitUtil.check(status, 0)); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 1)); + position.set(Position.KEY_CHARGE, BitUtil.check(status, 2)); + + sendResponse(channel, false, type, null); + + return position; + + } else if (type == MSG_ADDRESS_REQUEST) { + + String response = "NA&&NA&&0##"; + ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + content.writeByte(response.length()); + content.writeInt(0); + content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); + sendResponse(channel, true, MSG_ADDRESS_RESPONSE, content); + + } else if (type == MSG_TIME_REQUEST) { + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + content.writeByte(calendar.get(Calendar.YEAR) - 2000); + content.writeByte(calendar.get(Calendar.MONTH) + 1); + content.writeByte(calendar.get(Calendar.DAY_OF_MONTH)); + content.writeByte(calendar.get(Calendar.HOUR_OF_DAY)); + content.writeByte(calendar.get(Calendar.MINUTE)); + content.writeByte(calendar.get(Calendar.SECOND)); + sendResponse(channel, false, MSG_TIME_REQUEST, content); + } else if (type == MSG_X1_GPS) { Position position = new Position(); @@ -385,48 +469,53 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_WIFI || type == MSG_WIFI_2) { - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); - - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - getLastLocation(position, dateBuilder.getDate()); + return decodeWifi(buf, deviceSession); - Network network = new Network(); + } else { - int wifiCount = buf.getByte(2); - for (int i = 0; i < wifiCount; i++) { - String mac = String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - network.addWifiAccessPoint(WifiAccessPoint.from(mac, buf.readUnsignedByte())); - } + return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - int cellCount = buf.readUnsignedByte(); - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); - } + } - position.setNetwork(network); + return null; + } - return position; + private Object decodeWifi(ChannelBuffer buf, DeviceSession deviceSession) throws Exception { - } else { + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - return decodeBasicOther(channel, buf, deviceSession, type, dataLength); + DateBuilder dateBuilder = new DateBuilder() + .setYear(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setDay(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)); + getLastLocation(position, dateBuilder.getDate()); + + Network network = new Network(); + + int wifiCount = buf.getByte(2); + for (int i = 0; i < wifiCount; i++) { + String mac = String.format("%02x:%02x:%02x:%02x:%02x:%02x", + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + network.addWifiAccessPoint(WifiAccessPoint.from(mac, buf.readUnsignedByte())); + } + int cellCount = buf.readUnsignedByte(); + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); } - return null; + position.setNetwork(network); + + return position; } private Object decodeBasicOther(Channel channel, ChannelBuffer buf, @@ -436,7 +525,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.setProtocol(getProtocolName()); - if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { + if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI + || type == MSG_LBS_2 || type == MSG_WIFI_3) { + + boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3; DateBuilder dateBuilder = new DateBuilder(timeZone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -448,8 +540,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mnc = buf.readUnsignedByte(); Network network = new Network(); for (int i = 0; i < 7; i++) { - int lac = buf.readUnsignedShort(); - int cid = buf.readUnsignedMedium(); + int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); + int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); int rssi = -buf.readUnsignedByte(); if (lac > 0) { network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); @@ -458,7 +550,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // time leads - if (type != MSG_LBS_MULTIPLE) { + if (type != MSG_LBS_MULTIPLE && type != MSG_LBS_2) { int wifiCount = buf.readUnsignedByte(); for (int i = 0; i < wifiCount; i++) { String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); diff --git a/src/org/traccar/protocol/Jt600FrameDecoder.java b/src/org/traccar/protocol/Jt600FrameDecoder.java index 5606ae1fc..261f46fe8 100644 --- a/src/org/traccar/protocol/Jt600FrameDecoder.java +++ b/src/org/traccar/protocol/Jt600FrameDecoder.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. @@ -37,7 +37,7 @@ public class Jt600FrameDecoder extends FrameDecoder { if (type == '$') { boolean longFormat = buf.getUnsignedByte(buf.readerIndex() + 1) == 0x75; int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10; - if (length >= buf.readableBytes()) { + if (length <= buf.readableBytes()) { return buf.readBytes(length); } } else if (type == '(') { diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 15a71c88b..68c143257 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -16,15 +16,11 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; -import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; import org.jboss.netty.handler.codec.http.QueryStringDecoder; import org.joda.time.format.ISODateTimeFormat; -import org.traccar.BaseProtocolDecoder; +import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.model.Position; @@ -36,20 +32,12 @@ import java.util.Date; import java.util.List; import java.util.Map; -public class OsmAndProtocolDecoder extends BaseProtocolDecoder { +public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { public OsmAndProtocolDecoder(OsmAndProtocol protocol) { super(protocol); } - private void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); - response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 0); - channel.write(response); - } - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java index f3284d9e2..49d1cff96 100644 --- a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -17,39 +17,26 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; -import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; -import org.traccar.BaseProtocolDecoder; +import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; -import org.traccar.model.Position; import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import javax.json.Json; +import javax.json.JsonObject; +import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; -import java.io.StringReader; -import javax.json.Json; -import javax.json.JsonObject; - -public class OwnTracksProtocolDecoder extends BaseProtocolDecoder { +public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { public OwnTracksProtocolDecoder(OwnTracksProtocol protocol) { super(protocol); } - private void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); - response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 0); - channel.write(response); - } - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/org/traccar/protocol/SigfoxProtocol.java b/src/org/traccar/protocol/SigfoxProtocol.java new file mode 100644 index 000000000..9feaea12d --- /dev/null +++ b/src/org/traccar/protocol/SigfoxProtocol.java @@ -0,0 +1,47 @@ +/* + * 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.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.http.HttpChunkAggregator; +import org.jboss.netty.handler.codec.http.HttpRequestDecoder; +import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class SigfoxProtocol extends BaseProtocol { + + public SigfoxProtocol() { + super("sigfox"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpChunkAggregator(65535)); + pipeline.addLast("objectDecoder", new SigfoxProtocolDecoder(SigfoxProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java new file mode 100644 index 000000000..7cf57681f --- /dev/null +++ b/src/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -0,0 +1,91 @@ +/* + * 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.jboss.netty.channel.Channel; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.xml.bind.DatatypeConverter; +import java.io.StringReader; +import java.net.SocketAddress; +import java.net.URLDecoder; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { + + public SigfoxProtocolDecoder(SigfoxProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + HttpRequest request = (HttpRequest) msg; + JsonObject json = Json.createReader(new StringReader(URLDecoder.decode( + request.getContent().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device")); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(new Date(json.getInt("time") * 1000L)); + + ChannelBuffer buf = ChannelBuffers.wrappedBuffer( + ByteOrder.LITTLE_ENDIAN, DatatypeConverter.parseHexBinary(json.getString("data"))); + + int type = buf.readUnsignedByte() >> 4; + if (type == 0) { + + position.setValid(true); + position.setLatitude(buf.readInt() * 0.0000001); + position.setLongitude(buf.readInt() * 0.0000001); + position.setCourse(buf.readUnsignedByte() * 2); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025); + + } else { + + getLastLocation(position, position.getDeviceTime()); + + } + + position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue()); + position.set(Position.KEY_INDEX, json.getInt("seqNumber")); + + sendResponse(channel, HttpResponseStatus.OK); + return position; + } + +} diff --git a/src/org/traccar/protocol/StarcomProtocol.java b/src/org/traccar/protocol/StarcomProtocol.java new file mode 100644 index 000000000..f29d54bfe --- /dev/null +++ b/src/org/traccar/protocol/StarcomProtocol.java @@ -0,0 +1,45 @@ +/* + * 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.bootstrap.ConnectionlessBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class StarcomProtocol extends BaseProtocol { + + public StarcomProtocol() { + super("starcom"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new StarcomProtocolDecoder(StarcomProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/StarcomProtocolDecoder.java b/src/org/traccar/protocol/StarcomProtocolDecoder.java new file mode 100644 index 000000000..42c7ba12f --- /dev/null +++ b/src/org/traccar/protocol/StarcomProtocolDecoder.java @@ -0,0 +1,121 @@ +/* + * 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.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.SimpleDateFormat; + +public class StarcomProtocolDecoder extends BaseProtocolDecoder { + + public StarcomProtocolDecoder(StarcomProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + sentence = sentence.substring(sentence.indexOf('|') + 1, sentence.lastIndexOf('|')); + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + for (String entry : sentence.split(",")) { + int delimiter = entry.indexOf('='); + String key = entry.substring(0, delimiter); + String value = entry.substring(delimiter + 1); + switch (key) { + case "unit": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + break; + case "gps_valid": + position.setValid(Integer.parseInt(value) != 0); + break; + case "datetime_utc": + position.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(value)); + break; + case "latitude": + position.setLatitude(Double.parseDouble(value)); + break; + case "longitude": + position.setLongitude(Double.parseDouble(value)); + break; + case "altitude": + position.setAltitude(Double.parseDouble(value)); + break; + case "velocity": + position.setSpeed(Integer.parseInt(value)); + break; + case "heading": + position.setCourse(Integer.parseInt(value)); + break; + case "eventid": + position.set(Position.KEY_EVENT, Integer.parseInt(value)); + break; + case "odometer": + position.set(Position.KEY_ODOMETER, Long.parseLong(value)); + break; + case "satellites": + position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + break; + case "ignition": + position.set(Position.KEY_IGNITION, Integer.parseInt(value) != 0); + break; + case "door": + position.set(Position.KEY_DOOR, Integer.parseInt(value) != 0); + break; + case "arm": + position.set(Position.KEY_ARMED, Integer.parseInt(value) != 0); + break; + case "fuel": + position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(value)); + break; + case "rpm": + position.set(Position.KEY_RPM, Integer.parseInt(value)); + break; + case "main_voltage": + position.set(Position.KEY_POWER, Double.parseDouble(value)); + break; + case "backup_voltage": + position.set(Position.KEY_BATTERY, Double.parseDouble(value)); + break; + case "analog1": + case "analog2": + case "analog3": + position.set(Position.PREFIX_ADC + (key.charAt(key.length() - 1) - '0'), Double.parseDouble(value)); + break; + case "extra1": + case "extra2": + case "extra3": + position.set(key, value); + default: + break; + } + } + + return position; + } + +} |