aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debug.xml15
-rw-r--r--schema/changelog-3.7.xml35
-rw-r--r--schema/changelog-master.xml1
-rw-r--r--setup/unix/traccar.xml9
-rw-r--r--setup/windows/traccar.xml9
-rw-r--r--src/org/traccar/BaseProtocol.java2
-rw-r--r--src/org/traccar/Context.java11
-rw-r--r--src/org/traccar/api/resource/UserResource.java8
-rw-r--r--src/org/traccar/database/DataManager.java14
-rw-r--r--src/org/traccar/database/NotificationManager.java3
-rw-r--r--src/org/traccar/database/QueryBuilder.java12
-rw-r--r--src/org/traccar/notification/EventForwarder.java75
-rw-r--r--src/org/traccar/protocol/AquilaProtocol.java2
-rw-r--r--src/org/traccar/protocol/Ardi01Protocol.java2
-rw-r--r--src/org/traccar/protocol/ArknavProtocol.java2
-rw-r--r--src/org/traccar/protocol/ArnaviProtocol.java2
-rw-r--r--src/org/traccar/protocol/AuroProtocol.java2
-rw-r--r--src/org/traccar/protocol/CarTrackProtocol.java2
-rw-r--r--src/org/traccar/protocol/DishaProtocol.java2
-rw-r--r--src/org/traccar/protocol/EasyTrackProtocol.java2
-rw-r--r--src/org/traccar/protocol/EelinkProtocolDecoder.java129
-rw-r--r--src/org/traccar/protocol/FoxProtocol.java2
-rw-r--r--src/org/traccar/protocol/FreedomProtocol.java2
-rw-r--r--src/org/traccar/protocol/GnxProtocol.java2
-rw-r--r--src/org/traccar/protocol/GotopProtocol.java2
-rw-r--r--src/org/traccar/protocol/GpsMarkerProtocol.java2
-rw-r--r--src/org/traccar/protocol/HaicomProtocol.java2
-rw-r--r--src/org/traccar/protocol/HomtecsProtocol.java2
-rwxr-xr-xsrc/org/traccar/protocol/KenjiProtocol.java2
-rw-r--r--src/org/traccar/protocol/SanavProtocol.java2
-rw-r--r--src/org/traccar/protocol/Stl060Protocol.java2
-rwxr-xr-xsrc/org/traccar/protocol/SupermateProtocol.java2
-rw-r--r--src/org/traccar/protocol/T55Protocol.java4
-rw-r--r--src/org/traccar/protocol/TaipProtocol.java4
-rw-r--r--src/org/traccar/protocol/TelicProtocol.java2
-rw-r--r--src/org/traccar/protocol/Tk103Protocol.java4
-rw-r--r--src/org/traccar/protocol/Tlt2hProtocol.java2
-rw-r--r--src/org/traccar/protocol/TopflytechProtocol.java2
-rw-r--r--src/org/traccar/protocol/Tt8850Protocol.java2
-rw-r--r--src/org/traccar/protocol/UproProtocol.java2
-rw-r--r--src/org/traccar/protocol/V680Protocol.java3
-rw-r--r--src/org/traccar/protocol/VisiontekProtocol.java2
-rw-r--r--src/org/traccar/protocol/XexunProtocol.java2
-rw-r--r--src/org/traccar/protocol/Xt013Protocol.java2
-rw-r--r--test/org/traccar/protocol/EelinkProtocolDecoderTest.java9
-rw-r--r--web/app/GeofenceConverter.js4
-rw-r--r--web/app/view/AttributesController.js4
-rw-r--r--web/app/view/GroupsController.js1
-rw-r--r--web/app/view/Notifications.js2
49 files changed, 344 insertions, 68 deletions
diff --git a/debug.xml b/debug.xml
index 227ba7b73..09a575450 100644
--- a/debug.xml
+++ b/debug.xml
@@ -48,6 +48,12 @@
<entry key='event.motionHandler'>true</entry>
<entry key='event.geofenceHandler'>true</entry>
+ <!--<entry key='event.forward.enable'>true</entry>
+ <entry key='event.forward.url'>http://localhost/</entry>
+ <entry key='event.forward.header'>
+ Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
+ </entry>-->
+
<!--<entry key='mail.smtp.host'>smtp.example.com</entry>
for STARTTLS
<entry key='mail.smtp.port'>587</entry>
@@ -112,8 +118,8 @@
</entry>
<entry key='database.insertUser'>
- INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat)
- VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat);
+ INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, attributes)
+ VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :attributes);
</entry>
<entry key='database.updateUser'>
@@ -127,7 +133,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -180,7 +187,7 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name) VALUES (:name);
+ INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
</entry>
<entry key='database.updateGroup'>
diff --git a/schema/changelog-3.7.xml b/schema/changelog-3.7.xml
new file mode 100644
index 000000000..5e836a99c
--- /dev/null
+++ b/schema/changelog-3.7.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<databaseChangeLog
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
+ logicalFilePath="changelog-3.7">
+
+ <changeSet author="author" id="changelog-3.7">
+
+ <update tableName="devices">
+ <column name="groupid"/>
+ <where>groupid NOT IN (SELECT id FROM groups)</where>
+ </update>
+
+ <addForeignKeyConstraint baseColumnNames="groupid" baseTableName="devices" constraintName="fk_device_group_groupid" onDelete="SET NULL" onUpdate="RESTRICT" referencedColumnNames="id" referencedTableName="groups"/>
+
+ <update tableName="groups">
+ <column name="groupid"/>
+ <where>groupid NOT IN (SELECT id FROM (SELECT id FROM groups) AS groups_ids)</where>
+ </update>
+
+ </changeSet>
+
+ <changeSet author="author" id="changelog-3.7-notmssql">
+
+ <preConditions onFail="MARK_RAN">
+ <not>
+ <dbms type="mssql" />
+ </not>
+ </preConditions>
+ <addForeignKeyConstraint baseColumnNames="groupid" baseTableName="groups" constraintName="fk_group_group_groupid" onDelete="SET NULL" onUpdate="RESTRICT" referencedColumnNames="id" referencedTableName="groups"/>
+
+ </changeSet>
+</databaseChangeLog>
diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml
index 399cd3c8d..3b62537d0 100644
--- a/schema/changelog-master.xml
+++ b/schema/changelog-master.xml
@@ -8,4 +8,5 @@
<include file="changelog-3.3.xml" relativeToChangelogFile="true" />
<include file="changelog-3.5.xml" relativeToChangelogFile="true" />
<include file="changelog-3.6.xml" relativeToChangelogFile="true" />
+ <include file="changelog-3.7.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
diff --git a/setup/unix/traccar.xml b/setup/unix/traccar.xml
index 767d53d8b..a8bf9c334 100644
--- a/setup/unix/traccar.xml
+++ b/setup/unix/traccar.xml
@@ -70,8 +70,8 @@
</entry>
<entry key='database.insertUser'>
- INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat)
- VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat);
+ INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, attributes)
+ VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :attributes);
</entry>
<entry key='database.updateUser'>
@@ -85,7 +85,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -138,7 +139,7 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name) VALUES (:name);
+ INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
</entry>
<entry key='database.updateGroup'>
diff --git a/setup/windows/traccar.xml b/setup/windows/traccar.xml
index 8499bda67..a67d8c53c 100644
--- a/setup/windows/traccar.xml
+++ b/setup/windows/traccar.xml
@@ -70,8 +70,8 @@
</entry>
<entry key='database.insertUser'>
- INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat)
- VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat);
+ INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, attributes)
+ VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :attributes);
</entry>
<entry key='database.updateUser'>
@@ -85,7 +85,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -138,7 +139,7 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name) VALUES (:name);
+ INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
</entry>
<entry key='database.updateGroup'>
diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java
index 352895629..4a3e63db4 100644
--- a/src/org/traccar/BaseProtocol.java
+++ b/src/org/traccar/BaseProtocol.java
@@ -33,6 +33,7 @@ public abstract class BaseProtocol implements Protocol {
public BaseProtocol(String name) {
this.name = name;
+ supportedCommands.add(Command.TYPE_CUSTOM);
}
@Override
@@ -42,7 +43,6 @@ public abstract class BaseProtocol implements Protocol {
public void setSupportedCommands(String... commands) {
supportedCommands.addAll(Arrays.asList(commands));
- supportedCommands.add(Command.TYPE_CUSTOM);
}
@Override
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index ebe700221..0bb18b675 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -35,6 +35,7 @@ import org.traccar.helper.Log;
import org.traccar.location.LocationProvider;
import org.traccar.location.MozillaLocationProvider;
import org.traccar.location.OpenCellIdLocationProvider;
+import org.traccar.notification.EventForwarder;
import org.traccar.web.WebServer;
public final class Context {
@@ -120,6 +121,12 @@ public final class Context {
return ASYNC_HTTP_CLIENT;
}
+ private static EventForwarder eventForwarder;
+
+ public static EventForwarder getEventForvarder() {
+ return eventForwarder;
+ }
+
public static void init(String[] arguments) throws Exception {
config = new Config();
@@ -210,6 +217,10 @@ public final class Context {
serverManager = new ServerManager();
+ if (config.getBoolean("event.forward.enable")) {
+ eventForwarder = new EventForwarder();
+ }
+
}
public static void init(IdentityManager testIdentityManager) {
diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java
index cfe338b56..da72c7f47 100644
--- a/src/org/traccar/api/resource/UserResource.java
+++ b/src/org/traccar/api/resource/UserResource.java
@@ -52,9 +52,6 @@ public class UserResource extends BaseResource {
}
Context.getDataManager().addUser(entity);
Context.getPermissionsManager().refresh();
- if (Context.getGeofenceManager() != null) {
- Context.getGeofenceManager().refresh();
- }
if (Context.getNotificationManager() != null) {
Context.getNotificationManager().refresh();
}
@@ -71,9 +68,6 @@ public class UserResource extends BaseResource {
}
Context.getDataManager().updateUser(entity);
Context.getPermissionsManager().refresh();
- if (Context.getGeofenceManager() != null) {
- Context.getGeofenceManager().refresh();
- }
if (Context.getNotificationManager() != null) {
Context.getNotificationManager().refresh();
}
@@ -87,7 +81,7 @@ public class UserResource extends BaseResource {
Context.getDataManager().removeUser(id);
Context.getPermissionsManager().refresh();
if (Context.getGeofenceManager() != null) {
- Context.getGeofenceManager().refresh();
+ Context.getGeofenceManager().refreshUserGeofences();
}
if (Context.getNotificationManager() != null) {
Context.getNotificationManager().refresh();
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index b3f24383f..0dc3c5c52 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -401,9 +401,11 @@ public class DataManager implements IdentityManager {
QueryBuilder.create(dataSource, getQuery("database.updateDeviceStatus"))
.setObject(device)
.executeUpdate();
- Device cachedDevice = getDeviceById(device.getId());
- cachedDevice.setStatus(device.getStatus());
- cachedDevice.setMotion(device.getMotion());
+ if (devicesById.containsKey(device.getId())) {
+ Device cachedDevice = devicesById.get(device.getId());
+ cachedDevice.setStatus(device.getStatus());
+ cachedDevice.setMotion(device.getMotion());
+ }
}
public void removeDevice(long deviceId) throws SQLException {
@@ -512,8 +514,10 @@ public class DataManager implements IdentityManager {
.setDate("now", new Date())
.setObject(position)
.executeUpdate();
- Device device = getDeviceById(position.getDeviceId());
- device.setPositionId(position.getId());
+ if (devicesById.containsKey(position.getDeviceId())) {
+ Device cachedDevice = devicesById.get(position.getDeviceId());
+ cachedDevice.setPositionId(position.getId());
+ }
}
public Collection<Position> getLatestPositions() throws SQLException {
diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java
index e618d7ed3..911c5d2dc 100644
--- a/src/org/traccar/database/NotificationManager.java
+++ b/src/org/traccar/database/NotificationManager.java
@@ -68,6 +68,9 @@ public class NotificationManager {
}
}
}
+ if (Context.getEventForvarder() != null) {
+ Context.getEventForvarder().forwardEvent(event, position);
+ }
}
public void updateEvents(Collection<Event> events, Position position) {
diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java
index 73569ac2a..1a83daab9 100644
--- a/src/org/traccar/database/QueryBuilder.java
+++ b/src/org/traccar/database/QueryBuilder.java
@@ -173,9 +173,17 @@ public final class QueryBuilder {
}
public QueryBuilder setLong(String name, long value) throws SQLException {
+ return setLong(name, value, false);
+ }
+
+ public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException {
for (int i : indexes(name)) {
try {
- statement.setLong(i, value);
+ if (value == 0 && nullIfZero) {
+ statement.setNull(i, Types.INTEGER);
+ } else {
+ statement.setLong(i, value);
+ }
} catch (SQLException error) {
statement.close();
connection.close();
@@ -245,7 +253,7 @@ public final class QueryBuilder {
} else if (method.getReturnType().equals(int.class)) {
setInteger(name, (Integer) method.invoke(object));
} else if (method.getReturnType().equals(long.class)) {
- setLong(name, (Long) method.invoke(object));
+ setLong(name, (Long) method.invoke(object), name.endsWith("Id"));
} else if (method.getReturnType().equals(double.class)) {
setDouble(name, (Double) method.invoke(object));
} else if (method.getReturnType().equals(String.class)) {
diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java
new file mode 100644
index 000000000..096026541
--- /dev/null
+++ b/src/org/traccar/notification/EventForwarder.java
@@ -0,0 +1,75 @@
+package org.traccar.notification;
+
+import java.nio.charset.StandardCharsets;
+
+import javax.json.Json;
+import javax.json.JsonObjectBuilder;
+
+import org.traccar.Context;
+import org.traccar.model.Device;
+import org.traccar.model.Event;
+import org.traccar.model.Geofence;
+import org.traccar.model.Position;
+import org.traccar.web.JsonConverter;
+
+import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
+
+public final class EventForwarder {
+
+ private String url;
+ private String header;
+
+ public EventForwarder() {
+ url = Context.getConfig().getString("event.forward.url", "http://localhost/");
+ header = Context.getConfig().getString("event.forward.header", "");
+ }
+
+ private static final String USER_AGENT = "Traccar Server";
+
+ private static final String KEY_POSITION = "position";
+ private static final String KEY_EVENT = "event";
+ private static final String KEY_GEOFENCE = "geofence";
+ private static final String KEY_DEVICE = "device";
+
+ public void forwardEvent(Event event, Position position) {
+
+
+ BoundRequestBuilder requestBuilder = Context.getAsyncHttpClient().preparePost(url);
+
+ requestBuilder.addHeader("Content-Type", "application/json; charset=utf-8");
+ requestBuilder.addHeader("User-Agent", USER_AGENT);
+ if (!header.equals("")) {
+ String[] headerLines = header.split("\\r?\\n");
+ for (String headerLine: headerLines) {
+ String[] splitedLine = headerLine.split(":", 2);
+ if (splitedLine.length == 2) {
+ requestBuilder.addHeader(splitedLine[0].trim(), splitedLine[1].trim());
+ }
+ }
+ }
+
+ requestBuilder.setBody(preparePayload(event, position));
+ requestBuilder.execute();
+ }
+
+ private byte[] preparePayload(Event event, Position position) {
+ JsonObjectBuilder json = Json.createObjectBuilder();
+ json.add(KEY_EVENT, JsonConverter.objectToJson(event));
+ if (position != null) {
+ json.add(KEY_POSITION, JsonConverter.objectToJson(position));
+ }
+ if (event.getDeviceId() != 0) {
+ Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId());
+ if (device != null) {
+ json.add(KEY_DEVICE, JsonConverter.objectToJson(device));
+ }
+ }
+ if (event.getGeofenceId() != 0) {
+ Geofence geofence = Context.getGeofenceManager().getGeofence(event.getGeofenceId());
+ if (geofence != null) {
+ json.add(KEY_GEOFENCE, JsonConverter.objectToJson(geofence));
+ }
+ }
+ return json.build().toString().getBytes(StandardCharsets.UTF_8);
+ }
+}
diff --git a/src/org/traccar/protocol/AquilaProtocol.java b/src/org/traccar/protocol/AquilaProtocol.java
index 851efc40c..1bf5f4ee7 100644
--- a/src/org/traccar/protocol/AquilaProtocol.java
+++ b/src/org/traccar/protocol/AquilaProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class AquilaProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new AquilaProtocolDecoder(AquilaProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/Ardi01Protocol.java b/src/org/traccar/protocol/Ardi01Protocol.java
index 3bbb489f9..595692cc5 100644
--- a/src/org/traccar/protocol/Ardi01Protocol.java
+++ b/src/org/traccar/protocol/Ardi01Protocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class Ardi01Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Ardi01ProtocolDecoder(Ardi01Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/ArknavProtocol.java b/src/org/traccar/protocol/ArknavProtocol.java
index 13cb2572f..3b288b5ab 100644
--- a/src/org/traccar/protocol/ArknavProtocol.java
+++ b/src/org/traccar/protocol/ArknavProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class ArknavProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new ArknavProtocolDecoder(ArknavProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/ArnaviProtocol.java b/src/org/traccar/protocol/ArnaviProtocol.java
index 6afd0282d..5bdb68e86 100644
--- a/src/org/traccar/protocol/ArnaviProtocol.java
+++ b/src/org/traccar/protocol/ArnaviProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class ArnaviProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new ArnaviProtocolDecoder(ArnaviProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/AuroProtocol.java b/src/org/traccar/protocol/AuroProtocol.java
index cada65f72..e8fad85fd 100644
--- a/src/org/traccar/protocol/AuroProtocol.java
+++ b/src/org/traccar/protocol/AuroProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class AuroProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new AuroProtocolDecoder(AuroProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/CarTrackProtocol.java b/src/org/traccar/protocol/CarTrackProtocol.java
index e202ab65a..8a60e3ebb 100644
--- a/src/org/traccar/protocol/CarTrackProtocol.java
+++ b/src/org/traccar/protocol/CarTrackProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class CarTrackProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new CarTrackProtocolDecoder(CarTrackProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/DishaProtocol.java b/src/org/traccar/protocol/DishaProtocol.java
index cdb3ed0ac..bb0d6cdf1 100644
--- a/src/org/traccar/protocol/DishaProtocol.java
+++ b/src/org/traccar/protocol/DishaProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class DishaProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new DishaProtocolDecoder(DishaProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/EasyTrackProtocol.java b/src/org/traccar/protocol/EasyTrackProtocol.java
index 5a0a65ca2..d8bebeb5e 100644
--- a/src/org/traccar/protocol/EasyTrackProtocol.java
+++ b/src/org/traccar/protocol/EasyTrackProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class EasyTrackProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new EasyTrackProtocolDecoder(EasyTrackProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java
index 09cf1808f..e9de73dd5 100644
--- a/src/org/traccar/protocol/EelinkProtocolDecoder.java
+++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2014 - 2016 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
@@ -41,6 +42,16 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_INTERACTIVE = 0x80;
public static final int MSG_DATA = 0x81;
+ public static final int MSG_NORMAL = 0x12;
+ public static final int MSG_WARNING = 0x14;
+ public static final int MSG_REPORT = 0x15;
+ public static final int MSG_COMMAND = 0x16;
+ public static final int MSG_OBD_DATA = 0x17;
+ public static final int MSG_OBD_BODY = 0x18;
+ public static final int MSG_OBD_CODE = 0x19;
+ public static final int MSG_CAMERA_INFO = 0x1E;
+ public static final int MSG_CAMERA_DATA = 0x1F;
+
private void sendResponse(Channel channel, int type, int index) {
if (channel != null) {
ChannelBuffer response = ChannelBuffers.buffer(7);
@@ -52,57 +63,115 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodeOld(ChannelBuffer buf, int type, int index) {
- ChannelBuffer buf = (ChannelBuffer) msg;
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- buf.skipBytes(2); // header
- int type = buf.readUnsignedByte();
- buf.readShort(); // length
- int index = buf.readUnsignedShort();
+ position.set(Position.KEY_INDEX, index);
- if (type != MSG_GPS && type != MSG_DATA) {
- sendResponse(channel, type, index);
+ position.setTime(new Date(buf.readUnsignedInt() * 1000));
+ position.setLatitude(buf.readInt() / 1800000.0);
+ position.setLongitude(buf.readInt() / 1800000.0);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ position.setCourse(buf.readUnsignedShort());
+
+ position.set(Position.KEY_MCC, buf.readUnsignedShort());
+ position.set(Position.KEY_MNC, buf.readUnsignedShort());
+ position.set(Position.KEY_LAC, buf.readUnsignedShort());
+ position.set(Position.KEY_CID, buf.readUnsignedMedium());
+
+ position.setValid((buf.readUnsignedByte() & 0x01) != 0);
+
+ if (type == MSG_ALARM) {
+ position.set(Position.KEY_ALARM, buf.readUnsignedByte());
}
- if (type == MSG_LOGIN) {
+ if (type == MSG_STATE) {
+ position.set(Position.KEY_STATUS, buf.readUnsignedByte());
+ }
- identify(ChannelBuffers.hexDump(buf.readBytes(8)).substring(1), channel, remoteAddress);
+ return position;
+ }
+
+ private Position decodeNew(ChannelBuffer buf, int type, int index) {
+
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- } else if (hasDeviceId()
- && (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS)) {
+ position.set(Position.KEY_INDEX, index);
- Position position = new Position();
- position.setDeviceId(getDeviceId());
+ position.setTime(new Date(buf.readUnsignedInt() * 1000));
- position.setProtocol(getProtocolName());
- position.set(Position.KEY_INDEX, index);
+ int flags = buf.readUnsignedByte();
- position.setTime(new Date(buf.readUnsignedInt() * 1000));
+ if (BitUtil.check(flags, 0)) {
position.setLatitude(buf.readInt() / 1800000.0);
position.setLongitude(buf.readInt() / 1800000.0);
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ position.setAltitude(buf.readShort());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
position.setCourse(buf.readUnsignedShort());
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ }
+ if (BitUtil.check(flags, 1)) {
position.set(Position.KEY_MCC, buf.readUnsignedShort());
position.set(Position.KEY_MNC, buf.readUnsignedShort());
position.set(Position.KEY_LAC, buf.readUnsignedShort());
- position.set(Position.KEY_CID, buf.readUnsignedMedium());
+ position.set(Position.KEY_CID, buf.readUnsignedInt());
+ position.set(Position.KEY_GSM, buf.readUnsignedByte());
+ }
- position.setValid((buf.readUnsignedByte() & 0x01) != 0);
+ if (BitUtil.check(flags, 2)) {
+ buf.skipBytes(7); // bsid1
+ }
- if (type == MSG_ALARM) {
- position.set(Position.KEY_ALARM, buf.readUnsignedByte());
- }
+ if (BitUtil.check(flags, 3)) {
+ buf.skipBytes(7); // bsid2
+ }
- if (type == MSG_STATE) {
- position.set(Position.KEY_STATUS, buf.readUnsignedByte());
- }
+ if (BitUtil.check(flags, 4)) {
+ buf.skipBytes(7); // bss0
+ }
+
+ if (BitUtil.check(flags, 5)) {
+ buf.skipBytes(7); // bss1
+ }
+
+ if (BitUtil.check(flags, 6)) {
+ buf.skipBytes(7); // bss2
+ }
+
+ return position;
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
- return position;
+ buf.skipBytes(2); // header
+ int type = buf.readUnsignedByte();
+ buf.readShort(); // length
+ int index = buf.readUnsignedShort();
+ if (type != MSG_GPS && type != MSG_DATA) {
+ sendResponse(channel, type, index);
+ }
+
+ if (type == MSG_LOGIN) {
+
+ identify(ChannelBuffers.hexDump(buf.readBytes(8)).substring(1), channel, remoteAddress);
+
+ } else if (hasDeviceId()) {
+ if (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS) {
+ return decodeOld(buf, type, index);
+ } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) {
+ return decodeNew(buf, type, index);
+ }
}
return null;
diff --git a/src/org/traccar/protocol/FoxProtocol.java b/src/org/traccar/protocol/FoxProtocol.java
index cc069692b..bcda1e433 100644
--- a/src/org/traccar/protocol/FoxProtocol.java
+++ b/src/org/traccar/protocol/FoxProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class FoxProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "</fox>"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new FoxProtocolDecoder(FoxProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/FreedomProtocol.java b/src/org/traccar/protocol/FreedomProtocol.java
index 22d7792bc..2eb510cdb 100644
--- a/src/org/traccar/protocol/FreedomProtocol.java
+++ b/src/org/traccar/protocol/FreedomProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class FreedomProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new FreedomProtocolDecoder(FreedomProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/GnxProtocol.java b/src/org/traccar/protocol/GnxProtocol.java
index 7cbc14916..ff2976286 100644
--- a/src/org/traccar/protocol/GnxProtocol.java
+++ b/src/org/traccar/protocol/GnxProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class GnxProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\n\r"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new GnxProtocolDecoder(GnxProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/GotopProtocol.java b/src/org/traccar/protocol/GotopProtocol.java
index 5cec8f73c..303001756 100644
--- a/src/org/traccar/protocol/GotopProtocol.java
+++ b/src/org/traccar/protocol/GotopProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class GotopProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new GotopProtocolDecoder(GotopProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/GpsMarkerProtocol.java b/src/org/traccar/protocol/GpsMarkerProtocol.java
index 3ac827ea7..69c2637bd 100644
--- a/src/org/traccar/protocol/GpsMarkerProtocol.java
+++ b/src/org/traccar/protocol/GpsMarkerProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class GpsMarkerProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new GpsMarkerProtocolDecoder(GpsMarkerProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/HaicomProtocol.java b/src/org/traccar/protocol/HaicomProtocol.java
index de9e3ebb1..344f9c1ae 100644
--- a/src/org/traccar/protocol/HaicomProtocol.java
+++ b/src/org/traccar/protocol/HaicomProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class HaicomProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '*'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new HaicomProtocolDecoder(HaicomProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/HomtecsProtocol.java b/src/org/traccar/protocol/HomtecsProtocol.java
index 1a2e98565..8e65f8572 100644
--- a/src/org/traccar/protocol/HomtecsProtocol.java
+++ b/src/org/traccar/protocol/HomtecsProtocol.java
@@ -18,6 +18,7 @@ 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;
@@ -35,6 +36,7 @@ public class HomtecsProtocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new HomtecsProtocolDecoder(HomtecsProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/KenjiProtocol.java b/src/org/traccar/protocol/KenjiProtocol.java
index 6639021cb..8b196a9ed 100755
--- a/src/org/traccar/protocol/KenjiProtocol.java
+++ b/src/org/traccar/protocol/KenjiProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -38,6 +39,7 @@ public class KenjiProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new KenjiProtocolDecoder(KenjiProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/SanavProtocol.java b/src/org/traccar/protocol/SanavProtocol.java
index 29c0533ea..bb329ab70 100644
--- a/src/org/traccar/protocol/SanavProtocol.java
+++ b/src/org/traccar/protocol/SanavProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class SanavProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '*'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new SanavProtocolDecoder(SanavProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/Stl060Protocol.java b/src/org/traccar/protocol/Stl060Protocol.java
index 49e59e240..e37f94b00 100644
--- a/src/org/traccar/protocol/Stl060Protocol.java
+++ b/src/org/traccar/protocol/Stl060Protocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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;
@@ -36,6 +37,7 @@ public class Stl060Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new Stl060FrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Stl060ProtocolDecoder(Stl060Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/SupermateProtocol.java b/src/org/traccar/protocol/SupermateProtocol.java
index 12e773b9a..bcc2bed16 100755
--- a/src/org/traccar/protocol/SupermateProtocol.java
+++ b/src/org/traccar/protocol/SupermateProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class SupermateProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "#"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new SupermateProtocolDecoder(SupermateProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/T55Protocol.java b/src/org/traccar/protocol/T55Protocol.java
index 3fa0f6a9e..86f927e41 100644
--- a/src/org/traccar/protocol/T55Protocol.java
+++ b/src/org/traccar/protocol/T55Protocol.java
@@ -38,16 +38,16 @@ public class T55Protocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new T55ProtocolDecoder(T55Protocol.this));
}
});
serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new T55ProtocolDecoder(T55Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/TaipProtocol.java b/src/org/traccar/protocol/TaipProtocol.java
index a3b744e70..e72639099 100644
--- a/src/org/traccar/protocol/TaipProtocol.java
+++ b/src/org/traccar/protocol/TaipProtocol.java
@@ -38,16 +38,16 @@ public class TaipProtocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '<'));
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this, true));
}
});
serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this, false));
}
});
diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java
index 464892431..1e27620ba 100644
--- a/src/org/traccar/protocol/TelicProtocol.java
+++ b/src/org/traccar/protocol/TelicProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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;
@@ -37,6 +38,7 @@ public class TelicProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new TelicFrameDecoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new TelicProtocolDecoder(TelicProtocol.this));
}
};
diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java
index 324c01a31..b14264091 100644
--- a/src/org/traccar/protocol/Tk103Protocol.java
+++ b/src/org/traccar/protocol/Tk103Protocol.java
@@ -38,16 +38,16 @@ public class Tk103Protocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')'));
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Tk103ProtocolDecoder(Tk103Protocol.this));
}
});
serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Tk103ProtocolDecoder(Tk103Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/Tlt2hProtocol.java b/src/org/traccar/protocol/Tlt2hProtocol.java
index 14787537d..3a1bf99ff 100644
--- a/src/org/traccar/protocol/Tlt2hProtocol.java
+++ b/src/org/traccar/protocol/Tlt2hProtocol.java
@@ -37,8 +37,8 @@ public class Tlt2hProtocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n"));
- pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Tlt2hProtocolDecoder(Tlt2hProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/TopflytechProtocol.java b/src/org/traccar/protocol/TopflytechProtocol.java
index 42fa36c10..ae250ad02 100644
--- a/src/org/traccar/protocol/TopflytechProtocol.java
+++ b/src/org/traccar/protocol/TopflytechProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class TopflytechProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new TopflytechProtocolDecoder(TopflytechProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/Tt8850Protocol.java b/src/org/traccar/protocol/Tt8850Protocol.java
index a409205c7..db41fae9f 100644
--- a/src/org/traccar/protocol/Tt8850Protocol.java
+++ b/src/org/traccar/protocol/Tt8850Protocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class Tt8850Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "$"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Tt8850ProtocolDecoder(Tt8850Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/UproProtocol.java b/src/org/traccar/protocol/UproProtocol.java
index 36115edb4..b62247761 100644
--- a/src/org/traccar/protocol/UproProtocol.java
+++ b/src/org/traccar/protocol/UproProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class UproProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new UproProtocolDecoder(UproProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/V680Protocol.java b/src/org/traccar/protocol/V680Protocol.java
index d2ceb207b..4edff3772 100644
--- a/src/org/traccar/protocol/V680Protocol.java
+++ b/src/org/traccar/protocol/V680Protocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -38,6 +39,7 @@ public class V680Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##"));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this));
}
});
@@ -45,6 +47,7 @@ public class V680Protocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this));
}
});
diff --git a/src/org/traccar/protocol/VisiontekProtocol.java b/src/org/traccar/protocol/VisiontekProtocol.java
index 53d02c478..2d2a41e89 100644
--- a/src/org/traccar/protocol/VisiontekProtocol.java
+++ b/src/org/traccar/protocol/VisiontekProtocol.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class VisiontekProtocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#'));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new VisiontekProtocolDecoder(VisiontekProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/XexunProtocol.java b/src/org/traccar/protocol/XexunProtocol.java
index f99a3a9ee..14afaf4cb 100644
--- a/src/org/traccar/protocol/XexunProtocol.java
+++ b/src/org/traccar/protocol/XexunProtocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.Context;
import org.traccar.TrackerServer;
@@ -43,6 +44,7 @@ public class XexunProtocol extends BaseProtocol {
pipeline.addLast("frameDecoder", new XexunFrameDecoder());
}
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new XexunProtocolDecoder(XexunProtocol.this, full));
}
});
diff --git a/src/org/traccar/protocol/Xt013Protocol.java b/src/org/traccar/protocol/Xt013Protocol.java
index 14e0d3b9f..b11256b7d 100644
--- a/src/org/traccar/protocol/Xt013Protocol.java
+++ b/src/org/traccar/protocol/Xt013Protocol.java
@@ -19,6 +19,7 @@ import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -37,6 +38,7 @@ public class Xt013Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectDecoder", new Xt013ProtocolDecoder(Xt013Protocol.this));
}
});
diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
index d7a6c5e86..925e90dd6 100644
--- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
@@ -11,6 +11,15 @@ public class EelinkProtocolDecoderTest extends ProtocolTest {
EelinkProtocolDecoder decoder = new EelinkProtocolDecoder(new EelinkProtocol());
verifyNothing(decoder, binary(
+ "676701000c007b03525440717505180104"));
+
+ verifyPosition(decoder, binary(
+ "676712003400505784cc0b130246479b07d05a06001800000000070195039f046100002cc52e6466b391604a4900890e7c00000000000006ca"));
+
+ verifyPosition(decoder, binary(
+ "676714002b00515784cc24130246479b07d05a06001800010000060195039f046100002cc52f6466b391604a49020089"));
+
+ verifyNothing(decoder, binary(
"676701000c002603541880486128290120"));
verifyPosition(decoder, binary(
diff --git a/web/app/GeofenceConverter.js b/web/app/GeofenceConverter.js
index ebe121385..339f09615 100644
--- a/web/app/GeofenceConverter.js
+++ b/web/app/GeofenceConverter.js
@@ -20,7 +20,7 @@ Ext.define('Traccar.GeofenceConverter', {
wktToGeometry: function (mapView, wkt) {
var geometry, projection, resolutionAtEquator, pointResolution, resolutionFactor, points = [], center, radius,
content, i, lat, lon, coordinates;
- if (wkt.startsWith('POLYGON')) {
+ if (wkt.lastIndexOf('POLYGON', 0) === 0) {
content = wkt.match(/\([^\(\)]+\)/);
if (content !== null) {
coordinates = content[0].match(/-?\d+\.?\d*/g);
@@ -34,7 +34,7 @@ Ext.define('Traccar.GeofenceConverter', {
geometry = new ol.geom.Polygon([points]);
}
}
- } else if (wkt.startsWith('CIRCLE')) {
+ } else if (wkt.lastIndexOf('CIRCLE', 0) === 0) {
content = wkt.match(/\([^\(\)]+\)/);
if (content !== null) {
coordinates = content[0].match(/-?\d+\.?\d*/g);
diff --git a/web/app/view/AttributesController.js b/web/app/view/AttributesController.js
index 2a9e71849..8e6ab82a4 100644
--- a/web/app/view/AttributesController.js
+++ b/web/app/view/AttributesController.js
@@ -38,6 +38,7 @@ Ext.define('Traccar.view.AttributesController', {
}
}
store.addListener('add', function (store, records, index, eOpts) {
+ var i;
for (i = 0; i < records.length; i++) {
this.getView().record.get('attributes')[records[i].get('name')] = records[i].get('value');
}
@@ -53,7 +54,8 @@ Ext.define('Traccar.view.AttributesController', {
}
}, this);
store.addListener('remove', function (store, records, index, isMove, eOpts) {
- for (var i = 0; i < records.length; i++) {
+ var i;
+ for (i = 0; i < records.length; i++) {
delete this.getView().record.get('attributes')[records[i].get('name')];
}
this.getView().record.dirty = true;
diff --git a/web/app/view/GroupsController.js b/web/app/view/GroupsController.js
index 1764423d7..4cf1459a6 100644
--- a/web/app/view/GroupsController.js
+++ b/web/app/view/GroupsController.js
@@ -19,6 +19,7 @@ Ext.define('Traccar.view.GroupsController', {
alias: 'controller.groups',
requires: [
+ 'Traccar.view.GroupDialog',
'Traccar.view.GroupGeofences'
],
diff --git a/web/app/view/Notifications.js b/web/app/view/Notifications.js
index 996ce3748..5ff5f061f 100644
--- a/web/app/view/Notifications.js
+++ b/web/app/view/Notifications.js
@@ -30,7 +30,7 @@ Ext.define('Traccar.view.Notifications', {
},
viewConfig: {
- markDirty:false
+ markDirty: false
},
columns: [{