diff options
Diffstat (limited to 'src')
499 files changed, 8599 insertions, 5053 deletions
diff --git a/src/org/traccar/BaseDataHandler.java b/src/org/traccar/BaseDataHandler.java index 0c71a6a4d..8a461cc19 100644 --- a/src/org/traccar/BaseDataHandler.java +++ b/src/org/traccar/BaseDataHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,21 +15,19 @@ */ package org.traccar; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.model.Position; -public abstract class BaseDataHandler extends OneToOneDecoder { +public abstract class BaseDataHandler extends ChannelInboundHandlerAdapter { @Override - protected final Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof Position) { - return handlePosition((Position) msg); + ctx.fireChannelRead(handlePosition((Position) msg)); + } else { + super.channelRead(ctx, msg); } - - return msg; } protected abstract Position handlePosition(Position position); diff --git a/src/org/traccar/BaseEventHandler.java b/src/org/traccar/BaseEventHandler.java index b6f7e2085..50bbbefa2 100644 --- a/src/org/traccar/BaseEventHandler.java +++ b/src/org/traccar/BaseEventHandler.java @@ -24,7 +24,6 @@ public abstract class BaseEventHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Map<Event, Position> events = analyzePosition(position); if (events != null && Context.getNotificationManager() != null) { Context.getNotificationManager().updateEvents(events); diff --git a/src/org/traccar/BaseFrameDecoder.java b/src/org/traccar/BaseFrameDecoder.java new file mode 100644 index 000000000..f90f90e4b --- /dev/null +++ b/src/org/traccar/BaseFrameDecoder.java @@ -0,0 +1,37 @@ +/* + * Copyright 2018 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 io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +public abstract class BaseFrameDecoder extends ByteToMessageDecoder { + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { + Object decoded = decode(ctx, ctx != null ? ctx.channel() : null, in); + if (decoded != null) { + out.add(decoded); + } + } + + protected abstract Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception; + +} diff --git a/src/org/traccar/BaseHttpProtocolDecoder.java b/src/org/traccar/BaseHttpProtocolDecoder.java index 934a1b81e..57a68acac 100644 --- a/src/org/traccar/BaseHttpProtocolDecoder.java +++ b/src/org/traccar/BaseHttpProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,12 @@ */ 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; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; public abstract class BaseHttpProtocolDecoder extends BaseProtocolDecoder { @@ -30,9 +30,9 @@ public abstract class BaseHttpProtocolDecoder extends BaseProtocolDecoder { 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); + HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); + response.headers().add(HttpHeaderNames.CONTENT_LENGTH, 0); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 5a077da7c..6269fb8cc 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,20 +15,20 @@ */ package org.traccar; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelHandler; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.DownstreamMessageEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelHandler; -import org.jboss.netty.handler.logging.LoggingHandler; -import org.jboss.netty.handler.timeout.IdleStateHandler; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandler; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOutboundHandler; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelPromise; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.timeout.IdleStateHandler; import org.traccar.events.CommandResultEventHandler; import org.traccar.events.DriverEventHandler; import org.traccar.events.FuelDropEventHandler; @@ -44,13 +44,14 @@ import org.traccar.processing.CopyAttributesHandler; import java.net.InetSocketAddress; -public abstract class BasePipelineFactory implements ChannelPipelineFactory { +public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { private final TrackerServer server; private int timeout; private FilterHandler filterHandler; private DistanceHandler distanceHandler; + private EngineHoursHandler engineHoursHandler; private RemoteAddressHandler remoteAddressHandler; private MotionHandler motionHandler; private GeocoderHandler geocoderHandler; @@ -69,7 +70,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { private MaintenanceEventHandler maintenanceEventHandler; private DriverEventHandler driverEventHandler; - private static final class OpenChannelHandler extends SimpleChannelHandler { + private static final class OpenChannelHandler extends ChannelDuplexHandler { private final TrackerServer server; @@ -78,41 +79,83 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { } @Override - public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) { - server.getChannelGroup().add(e.getChannel()); + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + server.getChannelGroup().add(ctx.channel()); } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + server.getChannelGroup().remove(ctx.channel()); + } + } - private static class StandardLoggingHandler extends LoggingHandler { + private static class NetworkMessageHandler extends ChannelDuplexHandler { @Override - public void log(ChannelEvent e) { - if (e instanceof MessageEvent) { - MessageEvent event = (MessageEvent) e; - StringBuilder msg = new StringBuilder(); - - msg.append("[").append(String.format("%08X", e.getChannel().getId())).append(": "); - msg.append(((InetSocketAddress) e.getChannel().getLocalAddress()).getPort()); - if (e instanceof DownstreamMessageEvent) { - msg.append(" > "); - } else { - msg.append(" < "); - } + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (ctx.channel() instanceof DatagramChannel) { + DatagramPacket packet = (DatagramPacket) msg; + ctx.fireChannelRead(new NetworkMessage(packet.content(), packet.sender())); + } else { + ByteBuf buffer = (ByteBuf) msg; + ctx.fireChannelRead(new NetworkMessage(buffer, ctx.channel().remoteAddress())); + } + } - if (event.getRemoteAddress() != null) { - msg.append(((InetSocketAddress) event.getRemoteAddress()).getHostString()); - } else { - msg.append("null"); - } - msg.append("]"); + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + NetworkMessage message = (NetworkMessage) msg; + if (ctx.channel() instanceof DatagramChannel) { + InetSocketAddress recipient = (InetSocketAddress) message.getRemoteAddress(); + InetSocketAddress sender = (InetSocketAddress) ctx.channel().localAddress(); + ctx.write(new DatagramPacket((ByteBuf) message.getMessage(), recipient, sender), promise); + } else { + ctx.write(message.getMessage(), promise); + } + } - if (event.getMessage() instanceof ChannelBuffer) { - msg.append(" HEX: "); - msg.append(ChannelBuffers.hexDump((ChannelBuffer) event.getMessage())); - } + } + + private static class StandardLoggingHandler extends ChannelDuplexHandler { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + log(ctx, false, msg); + super.channelRead(ctx, msg); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + log(ctx, true, msg); + super.write(ctx, msg, promise); + } - Log.debug(msg.toString()); + public void log(ChannelHandlerContext ctx, boolean downstream, Object o) { + NetworkMessage networkMessage = (NetworkMessage) o; + StringBuilder message = new StringBuilder(); + + message.append("[").append(ctx.channel().id().asShortText()).append(": "); + message.append(((InetSocketAddress) ctx.channel().localAddress()).getPort()); + if (downstream) { + message.append(" > "); + } else { + message.append(" < "); + } + + if (networkMessage.getRemoteAddress() != null) { + message.append(((InetSocketAddress) networkMessage.getRemoteAddress()).getHostString()); + } else { + message.append("null"); } + message.append("]"); + + message.append(" HEX: "); + message.append(ByteBufUtil.hexDump((ByteBuf) networkMessage.getMessage())); + + Log.debug(message.toString()); } } @@ -155,6 +198,10 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { motionHandler = new MotionHandler(Context.getTripsConfig().getSpeedThreshold()); + if (Context.getConfig().getBoolean("processing.engineHours.enable")) { + engineHoursHandler = new EngineHoursHandler(); + } + if (Context.getConfig().hasKey("location.latitudeHemisphere") || Context.getConfig().hasKey("location.longitudeHemisphere")) { hemisphereHandler = new HemisphereHandler(); @@ -181,20 +228,33 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { } } - protected abstract void addSpecificHandlers(ChannelPipeline pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline); @Override - public ChannelPipeline getPipeline() { - ChannelPipeline pipeline = Channels.pipeline(); - if (timeout > 0 && !server.isConnectionless()) { - pipeline.addLast("idleHandler", new IdleStateHandler(GlobalTimer.getTimer(), timeout, 0, 0)); + protected void initChannel(Channel channel) throws Exception { + final ChannelPipeline pipeline = channel.pipeline(); + if (timeout > 0 && !server.isDatagram()) { + pipeline.addLast("idleHandler", new IdleStateHandler(timeout, 0, 0)); } pipeline.addLast("openHandler", new OpenChannelHandler(server)); + pipeline.addLast("messageHandler", new NetworkMessageHandler()); if (Context.isLoggerEnabled()) { pipeline.addLast("logger", new StandardLoggingHandler()); } - addSpecificHandlers(pipeline); + addProtocolHandlers(new PipelineBuilder() { + @Override + public void addLast(String name, ChannelHandler handler) { + if (!(handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder)) { + if (handler instanceof ChannelInboundHandler) { + handler = new WrapperInboundHandler((ChannelInboundHandler) handler); + } else { + handler = new WrapperOutboundHandler((ChannelOutboundHandler) handler); + } + } + pipeline.addLast(name, handler); + } + }); if (geolocationHandler != null) { pipeline.addLast("location", geolocationHandler); @@ -225,6 +285,10 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { pipeline.addLast("motion", motionHandler); } + if (engineHoursHandler != null) { + pipeline.addLast("engineHours", engineHoursHandler); + } + if (copyAttributesHandler != null) { pipeline.addLast("copyAttributes", copyAttributesHandler); } @@ -279,7 +343,6 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { } pipeline.addLast("mainHandler", new MainEventHandler()); - return pipeline; } private void addDynamicHandlers(ChannelPipeline pipeline) { @@ -294,4 +357,5 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { } } } + } diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index 7265bd9c1..62ee99946 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,8 +15,7 @@ */ package org.traccar; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.buffer.Unpooled; import org.traccar.database.ActiveDevice; import org.traccar.helper.DataConverter; import org.traccar.model.Command; @@ -76,10 +75,10 @@ public abstract class BaseProtocol implements Protocol { activeDevice.write(command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { String data = command.getString(Command.KEY_DATA); - if (activeDevice.getChannel().getPipeline().get(StringEncoder.class) != null) { + if (activeDevice.getChannel().pipeline().get("stringEncoder") != null) { activeDevice.write(data); } else { - activeDevice.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex(data))); + activeDevice.write(Unpooled.wrappedBuffer(DataConverter.parseHex(data))); } } else { throw new RuntimeException("Command " + command.getType() + " is not supported in protocol " + getName()); diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 3ea1208ca..fe41bd857 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -15,9 +15,8 @@ */ 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 io.netty.channel.Channel; +import io.netty.channel.socket.DatagramChannel; import org.traccar.helper.Log; import org.traccar.helper.UnitsConverter; import org.traccar.model.Device; @@ -145,7 +144,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - if (channel != null && channel.getPipeline().get(HttpRequestDecoder.class) != null + if (channel != null && channel.pipeline().get("httpDecoder") != null || Context.getConfig().getBoolean("decoder.ignoreSessionCache")) { long deviceId = findDeviceId(remoteAddress, uniqueIds); if (deviceId != 0) { diff --git a/src/org/traccar/BaseProtocolEncoder.java b/src/org/traccar/BaseProtocolEncoder.java index 2c8a81868..ed71b5551 100644 --- a/src/org/traccar/BaseProtocolEncoder.java +++ b/src/org/traccar/BaseProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,15 @@ */ package org.traccar; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; +import io.netty.channel.ChannelPromise; import org.traccar.helper.Log; import org.traccar.model.Command; import org.traccar.model.Device; -public abstract class BaseProtocolEncoder extends OneToOneEncoder { +public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { protected String getUniqueId(long deviceId) { return Context.getIdentityManager().getById(deviceId).getUniqueId(); @@ -41,15 +42,17 @@ public abstract class BaseProtocolEncoder extends OneToOneEncoder { } @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof Command) { - Command command = (Command) msg; - Object encodedCommand = encodeCommand(command); + NetworkMessage networkMessage = (NetworkMessage) msg; + + if (networkMessage.getMessage() instanceof Command) { + + Command command = (Command) networkMessage.getMessage(); + Object encodedCommand = encodeCommand(ctx.channel(), command); - // Log command StringBuilder s = new StringBuilder(); - s.append(String.format("[%08X] ", channel.getId())); + s.append("[").append(ctx.channel().id().asShortText()).append("] "); s.append("id: ").append(getUniqueId(command.getDeviceId())).append(", "); s.append("command type: ").append(command.getType()).append(" "); if (encodedCommand != null) { @@ -59,12 +62,21 @@ public abstract class BaseProtocolEncoder extends OneToOneEncoder { } Log.info(s.toString()); - return encodedCommand; + ctx.write(new NetworkMessage(encodedCommand, networkMessage.getRemoteAddress()), promise); + + } else { + + super.write(ctx, msg, promise); + } + } - return msg; + protected Object encodeCommand(Channel channel, Command command) { + return encodeCommand(command); } - protected abstract Object encodeCommand(Command command); + protected Object encodeCommand(Command command) { + return null; + } } diff --git a/src/org/traccar/CharacterDelimiterFrameDecoder.java b/src/org/traccar/CharacterDelimiterFrameDecoder.java index d71974e78..5175f9b37 100644 --- a/src/org/traccar/CharacterDelimiterFrameDecoder.java +++ b/src/org/traccar/CharacterDelimiterFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,27 +15,27 @@ */ package org.traccar; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.DelimiterBasedFrameDecoder; public class CharacterDelimiterFrameDecoder extends DelimiterBasedFrameDecoder { - private static ChannelBuffer createDelimiter(char delimiter) { + private static ByteBuf createDelimiter(char delimiter) { byte[] buf = {(byte) delimiter}; - return ChannelBuffers.wrappedBuffer(buf); + return Unpooled.wrappedBuffer(buf); } - private static ChannelBuffer createDelimiter(String delimiter) { + private static ByteBuf createDelimiter(String delimiter) { byte[] buf = new byte[delimiter.length()]; for (int i = 0; i < delimiter.length(); i++) { buf[i] = (byte) delimiter.charAt(i); } - return ChannelBuffers.wrappedBuffer(buf); + return Unpooled.wrappedBuffer(buf); } - private static ChannelBuffer[] convertDelimiters(String[] delimiters) { - ChannelBuffer[] result = new ChannelBuffer[delimiters.length]; + private static ByteBuf[] convertDelimiters(String[] delimiters) { + ByteBuf[] result = new ByteBuf[delimiters.length]; for (int i = 0; i < delimiters.length; i++) { result[i] = createDelimiter(delimiters[i]); } diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index abf9f7a8a..80be1ddc6 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -17,12 +17,14 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.ning.http.client.AsyncHttpClient; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Properties; +import com.fasterxml.jackson.datatype.jsr353.JSR353Module; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; import org.traccar.database.CalendarManager; @@ -35,6 +37,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; +import org.traccar.database.MaintenancesManager; import org.traccar.database.MediaManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; @@ -48,6 +51,7 @@ import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; +import org.traccar.geocoder.GeocodeXyzGeocoder; import org.traccar.geocoder.GisgraphyGeocoder; import org.traccar.geocoder.GoogleGeocoder; import org.traccar.geocoder.MapQuestGeocoder; @@ -64,6 +68,7 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; +import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.geolocation.GoogleGeolocationProvider; @@ -72,14 +77,19 @@ import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.notification.EventForwarder; import org.traccar.notification.JsonTypeEventForwarder; -import org.traccar.notification.MultiPartEventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.model.TripsConfig; import org.traccar.sms.SMSManager; import org.traccar.web.WebServer; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + public final class Context { + private static final String USER_AGENT = + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"; + private Context() { } @@ -209,10 +219,10 @@ public final class Context { return velocityEngine; } - private static final AsyncHttpClient ASYNC_HTTP_CLIENT = new AsyncHttpClient(); + private static Client client = ClientBuilder.newClient(); - public static AsyncHttpClient getAsyncHttpClient() { - return ASYNC_HTTP_CLIENT; + public static Client getClient() { + return client; } private static EventForwarder eventForwarder; @@ -239,6 +249,12 @@ public final class Context { return commandsManager; } + private static MaintenancesManager maintenancesManager; + + public static MaintenancesManager getMaintenancesManager() { + return maintenancesManager; + } + private static StatisticsManager statisticsManager; public static StatisticsManager getStatisticsManager() { @@ -310,6 +326,8 @@ public final class Context { return new FactualGeocoder(url, key, cacheSize, addressFormat); case "geocodefarm": return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); + case "geocodexyz": + return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); default: return new GoogleGeocoder(key, language, cacheSize, addressFormat); } @@ -330,12 +348,18 @@ public final class Context { } objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); if (Context.getConfig().getBoolean("mapper.prettyPrintedJson")) { objectMapper.enable(SerializationFeature.INDENT_OUTPUT); } + JacksonJsonProvider jsonProvider = + new JacksonJaxbJsonProvider(objectMapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS); + client = ClientBuilder.newClient().register(jsonProvider); + + if (config.hasKey("database.url")) { dataManager = new DataManager(config); } @@ -388,18 +412,14 @@ public final class Context { serverManager = new ServerManager(); if (config.getBoolean("event.forward.enable")) { - if (Context.getConfig().getBoolean("event.forward.payloadAsParamMode")) { - eventForwarder = new MultiPartEventForwarder(); - } else { - eventForwarder = new JsonTypeEventForwarder(); - } + eventForwarder = new JsonTypeEventForwarder(); } attributesManager = new AttributesManager(dataManager); driversManager = new DriversManager(dataManager); - commandsManager = new CommandsManager(dataManager); + commandsManager = new CommandsManager(dataManager, config.getBoolean("commands.queueing")); statisticsManager = new StatisticsManager(); @@ -431,6 +451,7 @@ public final class Context { geofenceManager = new GeofenceManager(dataManager); calendarManager = new CalendarManager(dataManager); + maintenancesManager = new MaintenancesManager(dataManager); notificationManager = new NotificationManager(dataManager); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); @@ -456,12 +477,17 @@ public final class Context { motionEventHandler = new MotionEventHandler(tripsConfig); overspeedEventHandler = new OverspeedEventHandler( Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000, - Context.getConfig().getBoolean("event.overspeed.notRepeat")); + Context.getConfig().getBoolean("event.overspeed.notRepeat"), + Context.getConfig().getBoolean("event.overspeed.preferLowest")); } public static void init(IdentityManager testIdentityManager) { config = new Config(); objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JSR353Module()); + JacksonJsonProvider jsonProvider = + new JacksonJaxbJsonProvider(objectMapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS); + client = ClientBuilder.newClient().register(jsonProvider); identityManager = testIdentityManager; } @@ -482,6 +508,8 @@ public final class Context { return (BaseObjectManager<T>) driversManager; } else if (clazz.equals(Command.class)) { return (BaseObjectManager<T>) commandsManager; + } else if (clazz.equals(Maintenance.class)) { + return (BaseObjectManager<T>) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager<T>) notificationManager; } diff --git a/src/org/traccar/DistanceHandler.java b/src/org/traccar/DistanceHandler.java index 295bc3b29..657f74edf 100644 --- a/src/org/traccar/DistanceHandler.java +++ b/src/org/traccar/DistanceHandler.java @@ -16,12 +16,14 @@ */ package org.traccar; +import io.netty.channel.ChannelHandler; import org.traccar.helper.DistanceCalculator; import org.traccar.model.Position; import java.math.BigDecimal; import java.math.RoundingMode; +@ChannelHandler.Sharable public class DistanceHandler extends BaseDataHandler { private final boolean filter; diff --git a/src/org/traccar/EngineHoursHandler.java b/src/org/traccar/EngineHoursHandler.java new file mode 100644 index 000000000..c9fbc186c --- /dev/null +++ b/src/org/traccar/EngineHoursHandler.java @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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 io.netty.channel.ChannelHandler; +import org.traccar.model.Position; + +@ChannelHandler.Sharable +public class EngineHoursHandler extends BaseDataHandler { + + @Override + protected Position handlePosition(Position position) { + if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { + Position last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + if (last != null) { + long hours = last.getLong(Position.KEY_HOURS); + if (last.getBoolean(Position.KEY_IGNITION) && position.getBoolean(Position.KEY_IGNITION)) { + hours += position.getFixTime().getTime() - last.getFixTime().getTime(); + } + if (hours != 0) { + position.set(Position.KEY_HOURS, hours); + } + } + } + return position; + } + +} diff --git a/src/org/traccar/EventLoopGroupFactory.java b/src/org/traccar/EventLoopGroupFactory.java new file mode 100644 index 000000000..482559253 --- /dev/null +++ b/src/org/traccar/EventLoopGroupFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012 - 2018 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 io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; + +public final class EventLoopGroupFactory { + + private static EventLoopGroup bossGroup = new NioEventLoopGroup(); + private static EventLoopGroup workerGroup = new NioEventLoopGroup(); + + private EventLoopGroupFactory() { + } + + public static EventLoopGroup getBossGroup() { + return bossGroup; + } + + public static EventLoopGroup getWorkerGroup() { + return workerGroup; + } + +} diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java index 75a24212f..681924e87 100644 --- a/src/org/traccar/ExtendedObjectDecoder.java +++ b/src/org/traccar/ExtendedObjectDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,12 @@ */ package org.traccar; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelUpstreamHandler; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.MessageEvent; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.ReferenceCountUtil; import org.traccar.helper.DataConverter; import org.traccar.model.Position; @@ -30,14 +28,14 @@ import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; -public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { +public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter { private void saveOriginal(Object decodedMessage, Object originalMessage) { if (Context.getConfig().getBoolean("database.saveOriginal") && decodedMessage instanceof Position) { Position position = (Position) decodedMessage; - if (originalMessage instanceof ChannelBuffer) { - ChannelBuffer buf = (ChannelBuffer) originalMessage; - position.set(Position.KEY_ORIGINAL, ChannelBuffers.hexDump(buf, 0, buf.writerIndex())); + if (originalMessage instanceof ByteBuf) { + ByteBuf buf = (ByteBuf) originalMessage; + position.set(Position.KEY_ORIGINAL, ByteBufUtil.hexDump(buf)); } else if (originalMessage instanceof String) { position.set(Position.KEY_ORIGINAL, DataConverter.printHex( ((String) originalMessage).getBytes(StandardCharsets.US_ASCII))); @@ -46,34 +44,28 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { } @Override - public void handleUpstream( - ChannelHandlerContext ctx, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - ctx.sendUpstream(evt); - return; - } - - MessageEvent e = (MessageEvent) evt; - Object originalMessage = e.getMessage(); - Object decodedMessage = decode(e.getChannel(), e.getRemoteAddress(), originalMessage); - onMessageEvent(e.getChannel(), e.getRemoteAddress(), originalMessage, decodedMessage); - if (originalMessage == decodedMessage) { - ctx.sendUpstream(evt); - } else { + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + NetworkMessage networkMessage = (NetworkMessage) msg; + Object originalMessage = networkMessage.getMessage(); + try { + Object decodedMessage = decode(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage); + onMessageEvent(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage, decodedMessage); if (decodedMessage == null) { - decodedMessage = handleEmptyMessage(e.getChannel(), e.getRemoteAddress(), originalMessage); + decodedMessage = handleEmptyMessage(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage); } if (decodedMessage != null) { if (decodedMessage instanceof Collection) { for (Object o : (Collection) decodedMessage) { saveOriginal(o, originalMessage); - Channels.fireMessageReceived(ctx, o, e.getRemoteAddress()); + ctx.fireChannelRead(o); } } else { saveOriginal(decodedMessage, originalMessage); - Channels.fireMessageReceived(ctx, decodedMessage, e.getRemoteAddress()); + ctx.fireChannelRead(decodedMessage); } } + } finally { + ReferenceCountUtil.release(originalMessage); } } diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 93f71d4e1..7ad68f386 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,10 +15,12 @@ */ package org.traccar; +import io.netty.channel.ChannelHandler; import org.traccar.helper.Log; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +@ChannelHandler.Sharable public class FilterHandler extends BaseDataHandler { private boolean filterInvalid; @@ -30,6 +32,7 @@ public class FilterHandler extends BaseDataHandler { private boolean filterStatic; private int filterDistance; private int filterMaxSpeed; + private long filterMinPeriod; private long skipLimit; private boolean skipAttributes; @@ -69,6 +72,10 @@ public class FilterHandler extends BaseDataHandler { this.filterMaxSpeed = filterMaxSpeed; } + public void setFilterMinPeriod(int filterMinPeriod) { + this.filterMinPeriod = filterMinPeriod; + } + public void setSkipLimit(long skipLimit) { this.skipLimit = skipLimit; } @@ -89,6 +96,7 @@ public class FilterHandler extends BaseDataHandler { filterStatic = config.getBoolean("filter.static"); filterDistance = config.getInteger("filter.distance"); filterMaxSpeed = config.getInteger("filter.maxSpeed"); + filterMinPeriod = config.getInteger("filter.minPeriod") * 1000; skipLimit = config.getLong("filter.skipLimit") * 1000; skipAttributes = config.getBoolean("filter.skipAttributes.enable"); } @@ -148,6 +156,14 @@ public class FilterHandler extends BaseDataHandler { return false; } + private boolean filterMinPeriod(Position position, Position last) { + if (filterMinPeriod != 0 && last != null) { + long time = position.getFixTime().getTime() - last.getFixTime().getTime(); + return time > 0 && time < filterMinPeriod; + } + return false; + } + private boolean skipLimit(Position position, Position last) { if (skipLimit != 0 && last != null) { return (position.getServerTime().getTime() - last.getServerTime().getTime()) > skipLimit; @@ -208,6 +224,9 @@ public class FilterHandler extends BaseDataHandler { if (filterMaxSpeed(position, last)) { filterType.append("MaxSpeed "); } + if (filterMinPeriod(position, last)) { + filterType.append("MinPeriod "); + } if (filterType.length() > 0) { @@ -216,8 +235,6 @@ public class FilterHandler extends BaseDataHandler { message.append(filterType.toString()); message.append("filters from device: "); message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); - message.append(" with id: "); - message.append(position.getDeviceId()); Log.info(message.toString()); return true; diff --git a/src/org/traccar/GeocoderHandler.java b/src/org/traccar/GeocoderHandler.java index 6b55e8162..0f3ba4731 100644 --- a/src/org/traccar/GeocoderHandler.java +++ b/src/org/traccar/GeocoderHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,16 +15,15 @@ */ package org.traccar; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelUpstreamHandler; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.MessageEvent; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.model.Position; -public class GeocoderHandler implements ChannelUpstreamHandler { +@ChannelHandler.Sharable +public class GeocoderHandler extends ChannelInboundHandlerAdapter { private final Geocoder geocoder; private final boolean processInvalidPositions; @@ -38,14 +37,7 @@ public class GeocoderHandler implements ChannelUpstreamHandler { } @Override - public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - ctx.sendUpstream(evt); - return; - } - - final MessageEvent event = (MessageEvent) evt; - Object message = event.getMessage(); + public void channelRead(final ChannelHandlerContext ctx, Object message) throws Exception { if (message instanceof Position) { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { @@ -54,7 +46,7 @@ public class GeocoderHandler implements ChannelUpstreamHandler { if (lastPosition != null && lastPosition.getAddress() != null && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { position.setAddress(lastPosition.getAddress()); - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); return; } } @@ -66,20 +58,20 @@ public class GeocoderHandler implements ChannelUpstreamHandler { @Override public void onSuccess(String address) { position.setAddress(address); - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } @Override public void onFailure(Throwable e) { Log.warning("Geocoding failed", e); - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } }); } else { - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } } else { - Channels.fireMessageReceived(ctx, message, event.getRemoteAddress()); + ctx.fireChannelRead(message); } } diff --git a/src/org/traccar/GeolocationHandler.java b/src/org/traccar/GeolocationHandler.java index 346ad5904..0c204dc0b 100644 --- a/src/org/traccar/GeolocationHandler.java +++ b/src/org/traccar/GeolocationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,16 +15,15 @@ */ package org.traccar; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelUpstreamHandler; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.MessageEvent; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.helper.Log; import org.traccar.geolocation.GeolocationProvider; import org.traccar.model.Position; -public class GeolocationHandler implements ChannelUpstreamHandler { +@ChannelHandler.Sharable +public class GeolocationHandler extends ChannelInboundHandlerAdapter { private final GeolocationProvider geolocationProvider; private final boolean processInvalidPositions; @@ -35,14 +34,7 @@ public class GeolocationHandler implements ChannelUpstreamHandler { } @Override - public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - ctx.sendUpstream(evt); - return; - } - - final MessageEvent event = (MessageEvent) evt; - Object message = event.getMessage(); + public void channelRead(final ChannelHandlerContext ctx, Object message) throws Exception { if (message instanceof Position) { final Position position = (Position) message; if ((position.getOutdated() || processInvalidPositions && !position.getValid()) @@ -63,20 +55,20 @@ public class GeolocationHandler implements ChannelUpstreamHandler { position.setSpeed(0); position.setCourse(0); position.set(Position.KEY_RSSI, 0); - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } @Override public void onFailure(Throwable e) { Log.warning(e); - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } }); } else { - Channels.fireMessageReceived(ctx, position, event.getRemoteAddress()); + ctx.fireChannelRead(position); } } else { - Channels.fireMessageReceived(ctx, message, event.getRemoteAddress()); + ctx.fireChannelRead(message); } } diff --git a/src/org/traccar/GlobalChannelFactory.java b/src/org/traccar/GlobalChannelFactory.java deleted file mode 100644 index c5cd1a697..000000000 --- a/src/org/traccar/GlobalChannelFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012 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.ChannelFactory; -import org.jboss.netty.channel.socket.DatagramChannelFactory; -import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; - -public final class GlobalChannelFactory { - - private static ChannelFactory channelFactory = null; - private static DatagramChannelFactory datagramChannelFactory = null; - - private GlobalChannelFactory() { - } - - public static void release() { - if (channelFactory != null) { - channelFactory.releaseExternalResources(); - } - if (datagramChannelFactory != null) { - datagramChannelFactory.releaseExternalResources(); - } - channelFactory = null; - datagramChannelFactory = null; - } - - public static ChannelFactory getFactory() { - if (channelFactory == null) { - channelFactory = new NioServerSocketChannelFactory(); - } - return channelFactory; - } - - public static DatagramChannelFactory getDatagramFactory() { - if (datagramChannelFactory == null) { - datagramChannelFactory = new NioDatagramChannelFactory(); - } - return datagramChannelFactory; - } - -} diff --git a/src/org/traccar/GlobalTimer.java b/src/org/traccar/GlobalTimer.java index 70e6e2e45..a97321ba2 100644 --- a/src/org/traccar/GlobalTimer.java +++ b/src/org/traccar/GlobalTimer.java @@ -15,8 +15,8 @@ */ package org.traccar; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timer; +import io.netty.util.HashedWheelTimer; +import io.netty.util.Timer; public final class GlobalTimer { diff --git a/src/org/traccar/HemisphereHandler.java b/src/org/traccar/HemisphereHandler.java index b1e7d3fb2..d1bcd340b 100644 --- a/src/org/traccar/HemisphereHandler.java +++ b/src/org/traccar/HemisphereHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar; -import org.jboss.netty.channel.Channel; +import io.netty.channel.ChannelHandler; import org.traccar.model.Position; -import java.net.SocketAddress; - -public class HemisphereHandler extends ExtendedObjectDecoder { +@ChannelHandler.Sharable +public class HemisphereHandler extends BaseDataHandler { private int latitudeFactor; private int longitudeFactor; @@ -45,20 +44,14 @@ public class HemisphereHandler extends ExtendedObjectDecoder { } @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - if (msg instanceof Position) { - Position position = (Position) msg; - if (latitudeFactor != 0) { - position.setLatitude(Math.abs(position.getLatitude()) * latitudeFactor); - } - if (longitudeFactor != 0) { - position.setLongitude(Math.abs(position.getLongitude()) * longitudeFactor); - } + protected Position handlePosition(Position position) { + if (latitudeFactor != 0) { + position.setLatitude(Math.abs(position.getLatitude()) * latitudeFactor); } - - return msg; + if (longitudeFactor != 0) { + position.setLongitude(Math.abs(position.getLongitude()) * longitudeFactor); + } + return position; } } diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index 8e88e15b9..49694aaff 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,14 +15,11 @@ */ package org.traccar; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; -import org.jboss.netty.handler.timeout.IdleStateEvent; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.socket.DatagramChannel; +import io.netty.handler.timeout.IdleStateEvent; import org.traccar.helper.Log; import org.traccar.model.Position; @@ -32,7 +29,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; -public class MainEventHandler extends IdleStateAwareChannelHandler { +public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set<String> connectionlessProtocols = new HashSet<>(); @@ -44,11 +41,10 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { } @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof Position) { - if (e.getMessage() != null && e.getMessage() instanceof Position) { - - Position position = (Position) e.getMessage(); + Position position = (Position) msg; try { Context.getDeviceManager().updateLatestPosition(position); } catch (SQLException error) { @@ -59,14 +55,19 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { // Log position StringBuilder s = new StringBuilder(); - s.append(formatChannel(e.getChannel())).append(" "); - s.append("id: ").append(uniqueId).append(", "); - s.append("time: ").append( - new SimpleDateFormat(Log.DATE_FORMAT).format(position.getFixTime())).append(", "); - s.append("lat: ").append(String.format("%.5f", position.getLatitude())).append(", "); - s.append("lon: ").append(String.format("%.5f", position.getLongitude())).append(", "); - s.append("speed: ").append(String.format("%.1f", position.getSpeed())).append(", "); - s.append("course: ").append(String.format("%.1f", position.getCourse())); + s.append(formatChannel(ctx.channel())).append(" "); + s.append("id: ").append(uniqueId); + s.append(", time: ").append( + new SimpleDateFormat(Log.DATE_FORMAT).format(position.getFixTime())); + s.append(", lat: ").append(String.format("%.5f", position.getLatitude())); + s.append(", lon: ").append(String.format("%.5f", position.getLongitude())); + if (position.getSpeed() > 0) { + s.append(", speed: ").append(String.format("%.1f", position.getSpeed())); + } + s.append(", course: ").append(String.format("%.1f", position.getCourse())); + if (position.getAccuracy() > 0) { + s.append(", accuracy: ").append(String.format("%.1f", position.getAccuracy())); + } Object cmdResult = position.getAttributes().get(Position.KEY_RESULT); if (cmdResult != null) { s.append(", result: ").append(cmdResult); @@ -78,36 +79,38 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { } private static String formatChannel(Channel channel) { - return String.format("[%08X]", channel.getId()); + return String.format("[%s]", channel.id().asShortText()); } @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { - Log.info(formatChannel(e.getChannel()) + " connected"); + public void channelActive(ChannelHandlerContext ctx) throws Exception { + Log.info(formatChannel(ctx.channel()) + " connected"); } @Override - public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) { - Log.info(formatChannel(e.getChannel()) + " disconnected"); - closeChannel(e.getChannel()); + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + Log.info(formatChannel(ctx.channel()) + " disconnected"); + closeChannel(ctx.channel()); - BaseProtocolDecoder protocolDecoder = (BaseProtocolDecoder) ctx.getPipeline().get("objectDecoder"); - if (ctx.getPipeline().get("httpDecoder") == null + BaseProtocolDecoder protocolDecoder = (BaseProtocolDecoder) ctx.pipeline().get("objectDecoder"); + if (ctx.pipeline().get("httpDecoder") == null && !connectionlessProtocols.contains(protocolDecoder.getProtocolName())) { - Context.getConnectionManager().removeActiveDevice(e.getChannel()); + Context.getConnectionManager().removeActiveDevice(ctx.channel()); } } @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - Log.warning(formatChannel(e.getChannel()) + " error", e.getCause()); - closeChannel(e.getChannel()); + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + Log.warning(formatChannel(ctx.channel()) + " error", cause); + closeChannel(ctx.channel()); } @Override - public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) { - Log.info(formatChannel(e.getChannel()) + " timed out"); - closeChannel(e.getChannel()); + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + Log.info(formatChannel(ctx.channel()) + " timed out"); + closeChannel(ctx.channel()); + } } private void closeChannel(Channel channel) { diff --git a/src/org/traccar/MotionHandler.java b/src/org/traccar/MotionHandler.java index 901965dd5..ec9a5ffd7 100644 --- a/src/org/traccar/MotionHandler.java +++ b/src/org/traccar/MotionHandler.java @@ -16,8 +16,10 @@ */ package org.traccar; +import io.netty.channel.ChannelHandler; import org.traccar.model.Position; +@ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { private double speedThreshold; diff --git a/src/org/traccar/NetworkMessage.java b/src/org/traccar/NetworkMessage.java new file mode 100644 index 000000000..14a397e69 --- /dev/null +++ b/src/org/traccar/NetworkMessage.java @@ -0,0 +1,38 @@ +/* + * Copyright 2018 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 java.net.SocketAddress; + +public class NetworkMessage { + + private final SocketAddress remoteAddress; + private final Object message; + + public NetworkMessage(Object message, SocketAddress remoteAddress) { + this.message = message; + this.remoteAddress = remoteAddress; + } + + public SocketAddress getRemoteAddress() { + return remoteAddress; + } + + public Object getMessage() { + return message; + } + +} diff --git a/src/org/traccar/PipelineBuilder.java b/src/org/traccar/PipelineBuilder.java new file mode 100644 index 000000000..20c40f159 --- /dev/null +++ b/src/org/traccar/PipelineBuilder.java @@ -0,0 +1,24 @@ +/* + * Copyright 2018 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 io.netty.channel.ChannelHandler; + +public interface PipelineBuilder { + + void addLast(String name, ChannelHandler handler); + +} diff --git a/src/org/traccar/Protocol.java b/src/org/traccar/Protocol.java index 87ac05298..c7aa67f9d 100644 --- a/src/org/traccar/Protocol.java +++ b/src/org/traccar/Protocol.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018 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.traccar.database.ActiveDevice; diff --git a/src/org/traccar/RemoteAddressHandler.java b/src/org/traccar/RemoteAddressHandler.java index 188bbcab9..aabc5715e 100644 --- a/src/org/traccar/RemoteAddressHandler.java +++ b/src/org/traccar/RemoteAddressHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,26 +15,28 @@ */ package org.traccar; -import org.jboss.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.model.Position; import java.net.InetSocketAddress; -import java.net.SocketAddress; -public class RemoteAddressHandler extends ExtendedObjectDecoder { +@ChannelHandler.Sharable +public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + public void channelRead(ChannelHandlerContext ctx, Object msg) { - String hostAddress = ((InetSocketAddress) remoteAddress).getAddress().getHostAddress(); + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; if (msg instanceof Position) { Position position = (Position) msg; position.set(Position.KEY_IP, hostAddress); } - return msg; + ctx.fireChannelRead(msg); } } diff --git a/src/org/traccar/ServerManager.java b/src/org/traccar/ServerManager.java index 45503b717..a8da6d57e 100644 --- a/src/org/traccar/ServerManager.java +++ b/src/org/traccar/ServerManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,7 +15,6 @@ */ package org.traccar; -import org.jboss.netty.channel.ChannelException; import org.traccar.helper.Log; import java.io.File; @@ -80,14 +79,12 @@ public class ServerManager { return protocolList.get(name); } - public void start() { + public void start() throws Exception { for (TrackerServer server: serverList) { try { server.start(); - } catch (ChannelException e) { - if (e.getCause() instanceof BindException) { - Log.warning("One of the protocols is disabled due to port conflict"); - } + } catch (BindException e) { + Log.warning("One of the protocols is disabled due to port conflict"); } } } @@ -96,7 +93,6 @@ public class ServerManager { for (TrackerServer server: serverList) { server.stop(); } - GlobalChannelFactory.release(); GlobalTimer.release(); } diff --git a/src/org/traccar/TrackerServer.java b/src/org/traccar/TrackerServer.java index 7e0a6f0c6..3a1e1c4e8 100644 --- a/src/org/traccar/TrackerServer.java +++ b/src/org/traccar/TrackerServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,55 +15,58 @@ */ package org.traccar; -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.buffer.HeapChannelBufferFactory; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.group.ChannelGroup; -import org.jboss.netty.channel.group.ChannelGroupFuture; -import org.jboss.netty.channel.group.DefaultChannelGroup; +import io.netty.bootstrap.AbstractBootstrap; +import io.netty.bootstrap.Bootstrap; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.util.concurrent.GlobalEventExecutor; import java.net.InetSocketAddress; -import java.nio.ByteOrder; public abstract class TrackerServer { - private final Bootstrap bootstrap; - private final String protocol; + private final boolean datagram; + private final AbstractBootstrap bootstrap; - public boolean isConnectionless() { - return bootstrap instanceof ConnectionlessBootstrap; + public boolean isDatagram() { + return datagram; } - public String getProtocol() { - return protocol; - } - - public TrackerServer(Bootstrap bootstrap, String protocol) { - this.bootstrap = bootstrap; - this.protocol = protocol; - - if (bootstrap instanceof ServerBootstrap) { - bootstrap.setFactory(GlobalChannelFactory.getFactory()); - } else if (bootstrap instanceof ConnectionlessBootstrap) { - bootstrap.setFactory(GlobalChannelFactory.getDatagramFactory()); - } + public TrackerServer(boolean datagram, String protocol) { + this.datagram = datagram; address = Context.getConfig().getString(protocol + ".address"); port = Context.getConfig().getInteger(protocol + ".port"); - bootstrap.setPipelineFactory(new BasePipelineFactory(this, protocol) { + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - TrackerServer.this.addSpecificHandlers(pipeline); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + TrackerServer.this.addProtocolHandlers(pipeline); } - }); + }; + + if (datagram) { + + this.bootstrap = new Bootstrap() + .group(EventLoopGroupFactory.getWorkerGroup()) + .channel(NioDatagramChannel.class) + .handler(pipelineFactory); + + } else { + + this.bootstrap = new ServerBootstrap() + .group(EventLoopGroupFactory.getBossGroup(), EventLoopGroupFactory.getWorkerGroup()) + .channel(NioServerSocketChannel.class) + .childHandler(pipelineFactory); + + } } - protected abstract void addSpecificHandlers(ChannelPipeline pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline); private int port; @@ -85,26 +88,13 @@ public abstract class TrackerServer { this.address = address; } - public void setEndianness(ByteOrder byteOrder) { - bootstrap.setOption("bufferFactory", new HeapChannelBufferFactory(byteOrder)); - bootstrap.setOption("child.bufferFactory", new HeapChannelBufferFactory(byteOrder)); - } - - private final ChannelGroup allChannels = new DefaultChannelGroup(); + private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); public ChannelGroup getChannelGroup() { - return allChannels; - } - - public void setPipelineFactory(ChannelPipelineFactory pipelineFactory) { - bootstrap.setPipelineFactory(pipelineFactory); + return channelGroup; } - public ChannelPipelineFactory getPipelineFactory() { - return bootstrap.getPipelineFactory(); - } - - public void start() { + public void start() throws Exception { InetSocketAddress endpoint; if (address == null) { endpoint = new InetSocketAddress(port); @@ -112,21 +102,14 @@ public abstract class TrackerServer { endpoint = new InetSocketAddress(address, port); } - Channel channel = null; - if (bootstrap instanceof ServerBootstrap) { - channel = ((ServerBootstrap) bootstrap).bind(endpoint); - } else if (bootstrap instanceof ConnectionlessBootstrap) { - channel = ((ConnectionlessBootstrap) bootstrap).bind(endpoint); - } - + Channel channel = bootstrap.bind(endpoint).sync().channel(); if (channel != null) { getChannelGroup().add(channel); } } public void stop() { - ChannelGroupFuture future = getChannelGroup().close(); - future.awaitUninterruptibly(); + channelGroup.close().awaitUninterruptibly(); } } diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java index cdd9d0c11..763493437 100644 --- a/src/org/traccar/WebDataHandler.java +++ b/src/org/traccar/WebDataHandler.java @@ -16,12 +16,12 @@ package org.traccar; import com.fasterxml.jackson.core.JsonProcessingException; -import com.ning.http.client.AsyncHttpClient; import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.Position; +import javax.ws.rs.client.Entity; import java.util.HashMap; import java.util.Map; import java.io.UnsupportedEncodingException; @@ -98,6 +98,7 @@ public class WebDataHandler extends BaseDataHandler { .replace("{altitude}", String.valueOf(position.getAltitude())) .replace("{speed}", String.valueOf(position.getSpeed())) .replace("{course}", String.valueOf(position.getCourse())) + .replace("{accuracy}", String.valueOf(position.getAccuracy())) .replace("{statusCode}", calculateStatus(position)); if (position.getAddress() != null) { @@ -129,21 +130,14 @@ public class WebDataHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { if (json) { - AsyncHttpClient.BoundRequestBuilder requestBuilder = Context.getAsyncHttpClient().preparePost(url); - requestBuilder.setBodyEncoding(StandardCharsets.UTF_8.name()); - - requestBuilder.addHeader("Content-Type", "application/json; charset=utf-8"); - - requestBuilder.setBody(prepareJsonPayload(position)); - requestBuilder.execute(); - + Context.getClient().target(url).request().async().post(Entity.json(prepareJsonPayload(position))); } else { - Context.getAsyncHttpClient().prepareGet(formatRequest(position)).execute(); + Context.getClient().target(formatRequest(position)).request().async().get(); } return position; } - protected String prepareJsonPayload(Position position) { + protected Map<String, Object> prepareJsonPayload(Position position) { Map<String, Object> data = new HashMap<>(); Device device = Context.getIdentityManager().getById(position.getDeviceId()); @@ -154,11 +148,7 @@ public class WebDataHandler extends BaseDataHandler { data.put(KEY_DEVICE, device); } - try { - return Context.getObjectMapper().writeValueAsString(data); - } catch (JsonProcessingException e) { - Log.warning(e); - return null; - } + return data; } + } diff --git a/src/org/traccar/WrapperContext.java b/src/org/traccar/WrapperContext.java new file mode 100644 index 000000000..372d3c60d --- /dev/null +++ b/src/org/traccar/WrapperContext.java @@ -0,0 +1,255 @@ +/* + * Copyright 2018 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 io.netty.buffer.ByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelProgressivePromise; +import io.netty.channel.ChannelPromise; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; +import io.netty.util.concurrent.EventExecutor; + +import java.net.SocketAddress; + +public class WrapperContext implements ChannelHandlerContext { + + private ChannelHandlerContext context; + private SocketAddress remoteAddress; + + public WrapperContext(ChannelHandlerContext context, SocketAddress remoteAddress) { + this.context = context; + this.remoteAddress = remoteAddress; + } + + @Override + public Channel channel() { + return context.channel(); + } + + @Override + public EventExecutor executor() { + return context.executor(); + } + + @Override + public String name() { + return context.name(); + } + + @Override + public ChannelHandler handler() { + return context.handler(); + } + + @Override + public boolean isRemoved() { + return context.isRemoved(); + } + + @Override + public ChannelHandlerContext fireChannelRegistered() { + return context.fireChannelRegistered(); + } + + @Override + public ChannelHandlerContext fireChannelUnregistered() { + return context.fireChannelUnregistered(); + } + + @Override + public ChannelHandlerContext fireChannelActive() { + return context.fireChannelActive(); + } + + @Override + public ChannelHandlerContext fireChannelInactive() { + return context.fireChannelInactive(); + } + + @Override + public ChannelHandlerContext fireExceptionCaught(Throwable cause) { + return context.fireExceptionCaught(cause); + } + + @Override + public ChannelHandlerContext fireUserEventTriggered(Object evt) { + return context.fireUserEventTriggered(evt); + } + + @Override + public ChannelHandlerContext fireChannelRead(Object msg) { + if (!(msg instanceof NetworkMessage)) { + msg = new NetworkMessage(msg, remoteAddress); + } + return context.fireChannelRead(msg); + } + + @Override + public ChannelHandlerContext fireChannelReadComplete() { + return context.fireChannelReadComplete(); + } + + @Override + public ChannelHandlerContext fireChannelWritabilityChanged() { + return context.fireChannelWritabilityChanged(); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress) { + return context.bind(localAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress) { + return context.connect(remoteAddress); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { + return context.connect(remoteAddress, localAddress); + } + + @Override + public ChannelFuture disconnect() { + return context.disconnect(); + } + + @Override + public ChannelFuture close() { + return context.close(); + } + + @Override + public ChannelFuture deregister() { + return context.deregister(); + } + + @Override + public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { + return context.bind(localAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) { + return context.connect(remoteAddress, promise); + } + + @Override + public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + return context.connect(remoteAddress, localAddress, promise); + } + + @Override + public ChannelFuture disconnect(ChannelPromise promise) { + return context.disconnect(promise); + } + + @Override + public ChannelFuture close(ChannelPromise promise) { + return context.close(promise); + } + + @Override + public ChannelFuture deregister(ChannelPromise promise) { + return context.deregister(promise); + } + + @Override + public ChannelHandlerContext read() { + return context.read(); + } + + @Override + public ChannelFuture write(Object msg) { + return context.write(msg); + } + + @Override + public ChannelFuture write(Object msg, ChannelPromise promise) { + if (!(msg instanceof NetworkMessage)) { + msg = new NetworkMessage(msg, remoteAddress); + } + return context.write(msg, promise); + } + + @Override + public ChannelHandlerContext flush() { + return context.flush(); + } + + @Override + public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) { + return context.writeAndFlush(msg, promise); + } + + @Override + public ChannelFuture writeAndFlush(Object msg) { + return context.writeAndFlush(msg); + } + + @Override + public ChannelPromise newPromise() { + return context.newPromise(); + } + + @Override + public ChannelProgressivePromise newProgressivePromise() { + return context.newProgressivePromise(); + } + + @Override + public ChannelFuture newSucceededFuture() { + return context.newSucceededFuture(); + } + + @Override + public ChannelFuture newFailedFuture(Throwable cause) { + return context.newFailedFuture(cause); + } + + @Override + public ChannelPromise voidPromise() { + return context.voidPromise(); + } + + @Override + public ChannelPipeline pipeline() { + return context.pipeline(); + } + + @Override + public ByteBufAllocator alloc() { + return context.alloc(); + } + + @SuppressWarnings("deprecation") + @Override + public <T> Attribute<T> attr(AttributeKey<T> key) { + return context.attr(key); + } + + @SuppressWarnings("deprecation") + @Override + public <T> boolean hasAttr(AttributeKey<T> key) { + return context.hasAttr(key); + } + +} diff --git a/src/org/traccar/WrapperInboundHandler.java b/src/org/traccar/WrapperInboundHandler.java new file mode 100644 index 000000000..f81f97108 --- /dev/null +++ b/src/org/traccar/WrapperInboundHandler.java @@ -0,0 +1,90 @@ +/* + * Copyright 2018 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 io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandler; + +public class WrapperInboundHandler implements ChannelInboundHandler { + + private ChannelInboundHandler handler; + + public WrapperInboundHandler(ChannelInboundHandler handler) { + this.handler = handler; + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + handler.channelRegistered(ctx); + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + handler.channelUnregistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + handler.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + handler.channelInactive(ctx); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof NetworkMessage) { + NetworkMessage nm = (NetworkMessage) msg; + handler.channelRead(new WrapperContext(ctx, nm.getRemoteAddress()), nm.getMessage()); + } else { + handler.channelRead(ctx, msg); + } + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + handler.channelReadComplete(ctx); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + handler.userEventTriggered(ctx, evt); + } + + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { + handler.channelWritabilityChanged(ctx); + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + handler.handlerAdded(ctx); + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + handler.handlerRemoved(ctx); + } + + @SuppressWarnings("deprecation") + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + handler.exceptionCaught(ctx, cause); + } + +} diff --git a/src/org/traccar/WrapperOutboundHandler.java b/src/org/traccar/WrapperOutboundHandler.java new file mode 100644 index 000000000..99afd9774 --- /dev/null +++ b/src/org/traccar/WrapperOutboundHandler.java @@ -0,0 +1,95 @@ +/* + * Copyright 2018 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 io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandler; +import io.netty.channel.ChannelPromise; + +import java.net.SocketAddress; + +public class WrapperOutboundHandler implements ChannelOutboundHandler { + + private ChannelOutboundHandler handler; + + public WrapperOutboundHandler(ChannelOutboundHandler handler) { + this.handler = handler; + } + + @Override + public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception { + handler.bind(ctx, localAddress, promise); + } + + @Override + public void connect( + ChannelHandlerContext ctx, SocketAddress remoteAddress, + SocketAddress localAddress, ChannelPromise promise) throws Exception { + handler.connect(ctx, remoteAddress, localAddress, promise); + } + + @Override + public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + handler.disconnect(ctx, promise); + } + + @Override + public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + handler.close(ctx, promise); + } + + @Override + public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + handler.deregister(ctx, promise); + } + + @Override + public void read(ChannelHandlerContext ctx) throws Exception { + handler.read(ctx); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (msg instanceof NetworkMessage) { + NetworkMessage nm = (NetworkMessage) msg; + handler.write(new WrapperContext(ctx, nm.getRemoteAddress()), nm.getMessage(), promise); + } else { + handler.write(ctx, msg, promise); + } + } + + @Override + public void flush(ChannelHandlerContext ctx) throws Exception { + handler.flush(ctx); + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + handler.handlerAdded(ctx); + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + handler.handlerRemoved(ctx); + } + + @SuppressWarnings("deprecation") + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + handler.exceptionCaught(ctx, cause); + } + +} diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java index 70ea7e3e1..227f80609 100644 --- a/src/org/traccar/api/CorsResponseFilter.java +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.api; -import org.jboss.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpHeaderNames; import org.traccar.Context; import javax.ws.rs.container.ContainerRequestContext; @@ -31,26 +31,26 @@ public class CorsResponseFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { - if (!response.getHeaders().containsKey(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_HEADERS)) { - response.getHeaders().add(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_HEADERS, HEADERS_ALL); + if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS.toString())) { + response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS.toString(), HEADERS_ALL); } - if (!response.getHeaders().containsKey(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_CREDENTIALS)) { - response.getHeaders().add(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_CREDENTIALS, true); + if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS.toString())) { + response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS.toString(), true); } - if (!response.getHeaders().containsKey(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_METHODS)) { - response.getHeaders().add(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_METHODS, METHODS_ALL); + if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS.toString())) { + response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS.toString(), METHODS_ALL); } - if (!response.getHeaders().containsKey(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN)) { - String origin = request.getHeaderString(HttpHeaders.Names.ORIGIN); + if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString())) { + String origin = request.getHeaderString(HttpHeaderNames.ORIGIN.toString()); String allowed = Context.getConfig().getString("web.origin"); if (origin == null) { - response.getHeaders().add(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, ORIGIN_ALL); + response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), ORIGIN_ALL); } else if (allowed == null || allowed.equals(ORIGIN_ALL) || allowed.contains(origin)) { - response.getHeaders().add(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, origin); + response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), origin); } } } diff --git a/src/org/traccar/api/resource/EventResource.java b/src/org/traccar/api/resource/EventResource.java index a7cf9edbd..e0ccf7020 100644 --- a/src/org/traccar/api/resource/EventResource.java +++ b/src/org/traccar/api/resource/EventResource.java @@ -13,6 +13,7 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Event; import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; @Path("events") @Produces(MediaType.APPLICATION_JSON) @@ -28,6 +29,9 @@ public class EventResource extends BaseResource { if (event.getGeofenceId() != 0) { Context.getPermissionsManager().checkPermission(Geofence.class, getUserId(), event.getGeofenceId()); } + if (event.getMaintenanceId() != 0) { + Context.getPermissionsManager().checkPermission(Maintenance.class, getUserId(), event.getMaintenanceId()); + } return event; } diff --git a/src/org/traccar/api/resource/MaintenanceResource.java b/src/org/traccar/api/resource/MaintenanceResource.java new file mode 100644 index 000000000..b3726b429 --- /dev/null +++ b/src/org/traccar/api/resource/MaintenanceResource.java @@ -0,0 +1,36 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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.api.resource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.traccar.api.ExtendedObjectResource; +import org.traccar.model.Maintenance; + +@Path("maintenances") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class MaintenanceResource extends ExtendedObjectResource<Maintenance> { + + public MaintenanceResource() { + super(Maintenance.class); + } + +} diff --git a/src/org/traccar/database/ActiveDevice.java b/src/org/traccar/database/ActiveDevice.java index f491111e1..207fc454b 100644 --- a/src/org/traccar/database/ActiveDevice.java +++ b/src/org/traccar/database/ActiveDevice.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,8 @@ */ package org.traccar.database; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; +import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Command; @@ -48,7 +49,7 @@ public class ActiveDevice { } public void write(Object message) { - getChannel().write(message, remoteAddress); + channel.writeAndFlush(new NetworkMessage(message, remoteAddress)); } } diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java index 2e68fae5a..c11f05f9b 100644 --- a/src/org/traccar/database/CommandsManager.java +++ b/src/org/traccar/database/CommandsManager.java @@ -37,8 +37,11 @@ public class CommandsManager extends ExtendedObjectManager<Command> { private final Map<Long, Queue<Command>> deviceQueues = new ConcurrentHashMap<>(); - public CommandsManager(DataManager dataManager) { + private boolean queueing; + + public CommandsManager(DataManager dataManager, boolean queueing) { super(dataManager, Command.class); + this.queueing = queueing; } public boolean checkDeviceCommand(long deviceId, long commandId) { @@ -70,6 +73,8 @@ public class CommandsManager extends ExtendedObjectManager<Command> { ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); if (activeDevice != null) { activeDevice.sendCommand(command); + } else if (!queueing) { + throw new RuntimeException("Device is not online"); } else { getDeviceQueue(deviceId).add(command); return false; diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index e5a7a272f..ef2085295 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.database; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.TimerTask; +import io.netty.channel.Channel; +import io.netty.util.Timeout; +import io.netty.util.TimerTask; import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.Protocol; @@ -57,9 +57,7 @@ public class ConnectionManager { } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - ActiveDevice activeDevice = new ActiveDevice(deviceId, protocol, channel, remoteAddress); - activeDevices.put(deviceId, activeDevice); - Context.getCommandsManager().sendQueuedCommands(activeDevice); + activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); } public void removeActiveDevice(Channel channel) { @@ -121,10 +119,9 @@ public class ConnectionManager { if (status.equals(Device.STATUS_ONLINE)) { timeouts.put(deviceId, GlobalTimer.getTimer().newTimeout(new TimerTask() { @Override - public void run(Timeout timeout) throws Exception { + public void run(Timeout timeout) { if (!timeout.isCancelled()) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); - activeDevices.remove(deviceId); } } }, deviceTimeout, TimeUnit.MILLISECONDS)); @@ -137,6 +134,10 @@ public class ConnectionManager { } updateDevice(device); + + if (status.equals(Device.STATUS_ONLINE) && !oldStatus.equals(Device.STATUS_ONLINE)) { + Context.getCommandsManager().sendQueuedCommands(getActiveDevice(deviceId)); + } } public Map<Event, Position> updateDeviceState(long deviceId) { diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index a997a89f6..06dd26b17 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -48,6 +48,7 @@ import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; +import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; import org.traccar.model.Permission; @@ -189,19 +190,19 @@ public class DataManager { public static String constructPermissionQuery(String action, Class<?> owner, Class<?> property) { switch (action) { - case ACTION_SELECT_ALL: - return "SELECT " + makeNameId(owner) + ", " + makeNameId(property) + " FROM " - + getPermissionsTableName(owner, property); - case ACTION_INSERT: - return "INSERT INTO " + getPermissionsTableName(owner, property) - + " (" + makeNameId(owner) + ", " + makeNameId(property) + ") VALUES (:" - + makeNameId(owner) + ", :" + makeNameId(property) + ")"; - case ACTION_DELETE: - return "DELETE FROM " + getPermissionsTableName(owner, property) - + " WHERE " + makeNameId(owner) + " = :" + makeNameId(owner) - + " AND " + makeNameId(property) + " = :" + makeNameId(property); - default: - throw new IllegalArgumentException("Unknown action"); + case ACTION_SELECT_ALL: + return "SELECT " + makeNameId(owner) + ", " + makeNameId(property) + " FROM " + + getPermissionsTableName(owner, property); + case ACTION_INSERT: + return "INSERT INTO " + getPermissionsTableName(owner, property) + + " (" + makeNameId(owner) + ", " + makeNameId(property) + ") VALUES (:" + + makeNameId(owner) + ", :" + makeNameId(property) + ")"; + case ACTION_DELETE: + return "DELETE FROM " + getPermissionsTableName(owner, property) + + " WHERE " + makeNameId(owner) + " = :" + makeNameId(owner) + + " AND " + makeNameId(property) + " = :" + makeNameId(property); + default: + throw new IllegalArgumentException("Unknown action"); } } @@ -272,11 +273,12 @@ public class DataManager { if (propertyName.equals("ManagedUser")) { propertyName = "User"; } - return Introspector.decapitalize(owner.getSimpleName()) + "_" + Introspector.decapitalize(propertyName); + return "tc_" + Introspector.decapitalize(owner.getSimpleName()) + + "_" + Introspector.decapitalize(propertyName); } private static String getObjectsTableName(Class<?> clazz) { - String result = Introspector.decapitalize(clazz.getSimpleName()); + String result = "tc_" + Introspector.decapitalize(clazz.getSimpleName()); // Add "s" ending if object name is not plural already if (!result.endsWith("s")) { result += "s"; @@ -294,7 +296,8 @@ public class DataManager { config.getString("database.url"), config.getString("database.user"), config.getString("database.password"), - null, resourceAccessor); + config.getString("database.driver"), + null, null, null, resourceAccessor); Liquibase liquibase = new Liquibase( config.getString("database.changelog"), resourceAccessor, database); @@ -405,6 +408,8 @@ public class DataManager { return Calendar.class; case "command": return Command.class; + case "maintenance": + return Maintenance.class; case "notification": return Notification.class; default: diff --git a/src/org/traccar/database/LdapProvider.java b/src/org/traccar/database/LdapProvider.java index 44dd386ed..eb975ad0f 100644 --- a/src/org/traccar/database/LdapProvider.java +++ b/src/org/traccar/database/LdapProvider.java @@ -150,7 +150,7 @@ public class LdapProvider { user.setEmail(accountName); } } - user.setAdmin(isAdmin(accountName)); + user.setAdministrator(isAdmin(accountName)); } catch (NamingException e) { user.setLogin(accountName); user.setName(accountName); diff --git a/src/org/traccar/database/MaintenancesManager.java b/src/org/traccar/database/MaintenancesManager.java new file mode 100644 index 000000000..4e266cb78 --- /dev/null +++ b/src/org/traccar/database/MaintenancesManager.java @@ -0,0 +1,27 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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.database; + +import org.traccar.model.Maintenance; + +public class MaintenancesManager extends ExtendedObjectManager<Maintenance> { + + public MaintenancesManager(DataManager dataManager) { + super(dataManager, Maintenance.class); + } + +} diff --git a/src/org/traccar/database/MediaManager.java b/src/org/traccar/database/MediaManager.java index 482442735..0bb6afac7 100644 --- a/src/org/traccar/database/MediaManager.java +++ b/src/org/traccar/database/MediaManager.java @@ -15,7 +15,7 @@ */ package org.traccar.database; -import org.jboss.netty.buffer.ChannelBuffer; +import io.netty.buffer.ByteBuf; import org.traccar.helper.Log; import java.io.File; @@ -46,13 +46,13 @@ public class MediaManager { return filePath.toFile(); } - public String writeFile(String uniqueId, ChannelBuffer buf, String extension) { + public String writeFile(String uniqueId, ByteBuf buf, String extension) { if (path != null) { int size = buf.readableBytes(); String name = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + "." + extension; try (FileOutputStream output = new FileOutputStream(createFile(uniqueId, name)); FileChannel fileChannel = output.getChannel()) { - ByteBuffer byteBuffer = buf.toByteBuffer(); + ByteBuffer byteBuffer = buf.nioBuffer(); int written = 0; while (written < size) { written += fileChannel.write(byteBuffer); diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java index a10fbf69a..2c1ffc09c 100644 --- a/src/org/traccar/database/NotificationManager.java +++ b/src/org/traccar/database/NotificationManager.java @@ -76,8 +76,10 @@ public class NotificationManager extends ExtendedObjectManager<Notification> { usersToForward = new HashSet<>(); } for (long userId : users) { - if (event.getGeofenceId() == 0 || Context.getGeofenceManager() != null - && Context.getGeofenceManager().checkItemPermission(userId, event.getGeofenceId())) { + if ((event.getGeofenceId() == 0 + || Context.getGeofenceManager().checkItemPermission(userId, event.getGeofenceId())) + && (event.getMaintenanceId() == 0 + || Context.getMaintenancesManager().checkItemPermission(userId, event.getMaintenanceId()))) { if (usersToForward != null) { usersToForward.add(userId); } diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 3ae5961ce..1c19f2374 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -25,6 +25,7 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; +import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; import org.traccar.model.Permission; @@ -155,7 +156,7 @@ public class PermissionsManager { public boolean getUserAdmin(long userId) { User user = getUser(userId); - return user != null && user.getAdmin(); + return user != null && user.getAdministrator(); } public void checkAdmin(long userId) throws SecurityException { @@ -257,7 +258,7 @@ public class PermissionsManager { } public void checkUserUpdate(long userId, User before, User after) throws SecurityException { - if (before.getAdmin() != after.getAdmin() + if (before.getAdministrator() != after.getAdministrator() || before.getDeviceLimit() != after.getDeviceLimit() || before.getUserLimit() != after.getUserLimit()) { checkAdmin(userId); @@ -337,6 +338,8 @@ public class PermissionsManager { manager = Context.getCalendarManager(); } else if (object.equals(Command.class)) { manager = Context.getCommandsManager(); + } else if (object.equals(Maintenance.class)) { + manager = Context.getMaintenancesManager(); } else if (object.equals(Notification.class)) { manager = Context.getNotificationManager(); } else { @@ -362,6 +365,7 @@ public class PermissionsManager { Context.getDriversManager().refreshUserItems(); Context.getAttributesManager().refreshUserItems(); Context.getCommandsManager().refreshUserItems(); + Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } @@ -374,6 +378,7 @@ public class PermissionsManager { Context.getDriversManager().refreshExtendedPermissions(); Context.getAttributesManager().refreshExtendedPermissions(); Context.getCommandsManager().refreshExtendedPermissions(); + Context.getMaintenancesManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -394,6 +399,8 @@ public class PermissionsManager { Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Command.class)) { Context.getCommandsManager().refreshUserItems(); + } else if (permission.getPropertyClass().equals(Maintenance.class)) { + Context.getMaintenancesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -407,6 +414,8 @@ public class PermissionsManager { Context.getAttributesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Command.class)) { Context.getCommandsManager().refreshExtendedPermissions(); + } else if (permission.getPropertyClass().equals(Maintenance.class)) { + Context.getMaintenancesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/org/traccar/database/StatisticsManager.java b/src/org/traccar/database/StatisticsManager.java index 9a3ff06bd..452cdffa0 100644 --- a/src/org/traccar/database/StatisticsManager.java +++ b/src/org/traccar/database/StatisticsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,13 +15,13 @@ */ package org.traccar.database; -import com.ning.http.client.Request; -import com.ning.http.client.RequestBuilder; import org.joda.time.format.ISODateTimeFormat; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Statistics; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Form; import java.sql.SQLException; import java.util.Calendar; import java.util.Date; @@ -70,22 +70,21 @@ public class StatisticsManager { String url = Context.getConfig().getString("server.statistics"); if (url != null) { String time = ISODateTimeFormat.dateTime().print(statistics.getCaptureTime().getTime()); - Request request = new RequestBuilder("POST") - .setUrl(url) - .addHeader("Content-Type", "application/x-www-form-urlencoded") - .addFormParam("version", Log.getAppVersion()) - .addFormParam("captureTime", time) - .addFormParam("activeUsers", String.valueOf(statistics.getActiveUsers())) - .addFormParam("activeDevices", String.valueOf(statistics.getActiveDevices())) - .addFormParam("requests", String.valueOf(statistics.getRequests())) - .addFormParam("messagesReceived", String.valueOf(statistics.getMessagesReceived())) - .addFormParam("messagesStored", String.valueOf(statistics.getMessagesStored())) - .addFormParam("mailSent", String.valueOf(statistics.getMailSent())) - .addFormParam("smsSent", String.valueOf(statistics.getSmsSent())) - .addFormParam("geocoderRequests", String.valueOf(statistics.getGeocoderRequests())) - .addFormParam("geolocationRequests", String.valueOf(statistics.getGeolocationRequests())) - .build(); - Context.getAsyncHttpClient().prepareRequest(request).execute(); + + Form form = new Form(); + form.param("version", Log.getAppVersion()); + form.param("captureTime", time); + form.param("activeUsers", String.valueOf(statistics.getActiveUsers())); + form.param("activeDevices", String.valueOf(statistics.getActiveDevices())); + form.param("requests", String.valueOf(statistics.getRequests())); + form.param("messagesReceived", String.valueOf(statistics.getMessagesReceived())); + form.param("messagesStored", String.valueOf(statistics.getMessagesStored())); + form.param("mailSent", String.valueOf(statistics.getMailSent())); + form.param("smsSent", String.valueOf(statistics.getSmsSent())); + form.param("geocoderRequests", String.valueOf(statistics.getGeocoderRequests())); + form.param("geolocationRequests", String.valueOf(statistics.getGeolocationRequests())); + + Context.getClient().target(url).request().async().post(Entity.form(form)); } users.clear(); diff --git a/src/org/traccar/events/AlertEventHandler.java b/src/org/traccar/events/AlertEventHandler.java index 7db371c70..b14869e72 100644 --- a/src/org/traccar/events/AlertEventHandler.java +++ b/src/org/traccar/events/AlertEventHandler.java @@ -18,11 +18,13 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; +@ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { private final boolean ignoreDuplicateAlerts; diff --git a/src/org/traccar/events/CommandResultEventHandler.java b/src/org/traccar/events/CommandResultEventHandler.java index 775aa903f..89ec44190 100644 --- a/src/org/traccar/events/CommandResultEventHandler.java +++ b/src/org/traccar/events/CommandResultEventHandler.java @@ -18,10 +18,12 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.model.Event; import org.traccar.model.Position; +@ChannelHandler.Sharable public class CommandResultEventHandler extends BaseEventHandler { @Override diff --git a/src/org/traccar/events/DriverEventHandler.java b/src/org/traccar/events/DriverEventHandler.java index 39b8eb9c0..c8efd0576 100644 --- a/src/org/traccar/events/DriverEventHandler.java +++ b/src/org/traccar/events/DriverEventHandler.java @@ -19,11 +19,13 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; +@ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { @Override diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index 2ee3e1a58..31b17d500 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -15,6 +15,7 @@ */ package org.traccar.events; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; @@ -24,6 +25,7 @@ import org.traccar.model.Position; import java.util.Collections; import java.util.Map; +@ChannelHandler.Sharable public class FuelDropEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_FUEL_DROP_THRESHOLD = "fuelDropThreshold"; diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 31d82a81e..ea379dbdb 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.database.GeofenceManager; @@ -28,6 +29,7 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +@ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { private GeofenceManager geofenceManager; diff --git a/src/org/traccar/events/IgnitionEventHandler.java b/src/org/traccar/events/IgnitionEventHandler.java index cc53b216c..a17f15318 100644 --- a/src/org/traccar/events/IgnitionEventHandler.java +++ b/src/org/traccar/events/IgnitionEventHandler.java @@ -19,12 +19,14 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +@ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { @Override diff --git a/src/org/traccar/events/MaintenanceEventHandler.java b/src/org/traccar/events/MaintenanceEventHandler.java index 86abf7c17..5bebb1baf 100644 --- a/src/org/traccar/events/MaintenanceEventHandler.java +++ b/src/org/traccar/events/MaintenanceEventHandler.java @@ -1,6 +1,6 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,54 +16,49 @@ */ package org.traccar.events; -import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; -import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Maintenance; import org.traccar.model.Position; +@ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { - public static final String ATTRIBUTE_MAINTENANCE_START = "maintenance.start"; - public static final String ATTRIBUTE_MAINTENANCE_INTERVAL = "maintenance.interval"; - @Override protected Map<Event, Position> analyzePosition(Position position) { - Device device = Context.getIdentityManager().getById(position.getDeviceId()); - if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { - return null; - } - - double maintenanceInterval = Context.getDeviceManager() - .lookupAttributeDouble(device.getId(), ATTRIBUTE_MAINTENANCE_INTERVAL, 0, false); - if (maintenanceInterval == 0) { + if (Context.getIdentityManager().getById(position.getDeviceId()) == null + || !Context.getIdentityManager().isLatestPosition(position)) { return null; } - double maintenanceStart = Context.getDeviceManager() - .lookupAttributeDouble(device.getId(), ATTRIBUTE_MAINTENANCE_START, 0, false); - - double oldTotalDistance = 0.0; - double newTotalDistance = 0.0; Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldTotalDistance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE); + if (lastPosition == null) { + return null; } - newTotalDistance = position.getDouble(Position.KEY_TOTAL_DISTANCE); - - oldTotalDistance -= maintenanceStart; - newTotalDistance -= maintenanceStart; - if ((long) (oldTotalDistance / maintenanceInterval) < (long) (newTotalDistance / maintenanceInterval)) { - Event event = new Event(Event.TYPE_MAINTENANCE, position.getDeviceId(), position.getId()); - event.set(Position.KEY_TOTAL_DISTANCE, newTotalDistance); - return Collections.singletonMap(event, position); + Map<Event, Position> events = new HashMap<>(); + for (long maintenanceId : Context.getMaintenancesManager().getAllDeviceItems(position.getDeviceId())) { + Maintenance maintenance = Context.getMaintenancesManager().getById(maintenanceId); + if (maintenance.getPeriod() != 0) { + double oldValue = lastPosition.getDouble(maintenance.getType()); + double newValue = position.getDouble(maintenance.getType()); + if (oldValue != 0.0 && newValue != 0.0 + && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) + < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { + Event event = new Event(Event.TYPE_MAINTENANCE, position.getDeviceId(), position.getId()); + event.setMaintenanceId(maintenanceId); + event.set(maintenance.getType(), newValue); + events.put(event, position); + } + } } - return null; + return events; } } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 0c1c4848f..4047b83a4 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -19,6 +19,7 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; @@ -28,6 +29,7 @@ import org.traccar.model.Position; import org.traccar.reports.ReportUtils; import org.traccar.reports.model.TripsConfig; +@ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { private TripsConfig tripsConfig; diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index cb658415c..4f9a35793 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -1,5 +1,6 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,23 +19,28 @@ package org.traccar.events; import java.util.Collections; import java.util.Map; +import io.netty.channel.ChannelHandler; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.DeviceState; import org.traccar.model.Event; +import org.traccar.model.Geofence; import org.traccar.model.Position; +@ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private boolean notRepeat; + private boolean preferLowest; private long minimalDuration; - public OverspeedEventHandler(long minimalDuration, boolean notRepeat) { + public OverspeedEventHandler(long minimalDuration, boolean notRepeat, boolean preferLowest) { this.notRepeat = notRepeat; this.minimalDuration = minimalDuration; + this.preferLowest = preferLowest; } private Map<Event, Position> newEvent(DeviceState deviceState, double speedLimit) { @@ -42,8 +48,10 @@ public class OverspeedEventHandler extends BaseEventHandler { Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); event.set("speed", deviceState.getOverspeedPosition().getSpeed()); event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + event.setGeofenceId(deviceState.getOverspeedGeofenceId()); deviceState.setOverspeedState(notRepeat); deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); return Collections.singletonMap(event, position); } @@ -61,7 +69,8 @@ public class OverspeedEventHandler extends BaseEventHandler { return result; } - public Map<Event, Position> updateOverspeedState(DeviceState deviceState, Position position, double speedLimit) { + public Map<Event, Position> updateOverspeedState( + DeviceState deviceState, Position position, double speedLimit, long geofenceId) { Map<Event, Position> result = null; Boolean oldOverspeed = deviceState.getOverspeedState(); @@ -71,12 +80,15 @@ public class OverspeedEventHandler extends BaseEventHandler { if (newOverspeed && !oldOverspeed) { if (deviceState.getOverspeedPosition() == null) { deviceState.setOverspeedPosition(position); + deviceState.setOverspeedGeofenceId(geofenceId); } } else if (oldOverspeed && !newOverspeed) { deviceState.setOverspeedState(false); deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); } else { deviceState.setOverspeedPosition(null); + deviceState.setOverspeedGeofenceId(0); } Position overspeedPosition = deviceState.getOverspeedPosition(); if (overspeedPosition != null) { @@ -101,6 +113,28 @@ public class OverspeedEventHandler extends BaseEventHandler { } double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); + + double geofenceSpeedLimit = 0; + long overspeedGeofenceId = 0; + + if (Context.getGeofenceManager() != null && device.getGeofenceIds() != null) { + for (long geofenceId : device.getGeofenceIds()) { + Geofence geofence = Context.getGeofenceManager().getById(geofenceId); + if (geofence != null) { + double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); + if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 + || preferLowest && currentSpeedLimit < geofenceSpeedLimit + || !preferLowest && currentSpeedLimit > geofenceSpeedLimit) { + geofenceSpeedLimit = currentSpeedLimit; + overspeedGeofenceId = geofenceId; + } + } + } + } + if (geofenceSpeedLimit > 0) { + speedLimit = geofenceSpeedLimit; + } + if (speedLimit == 0) { return null; } @@ -110,8 +144,9 @@ public class OverspeedEventHandler extends BaseEventHandler { if (deviceState.getOverspeedState() == null) { deviceState.setOverspeedState(position.getSpeed() > speedLimit); + deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0); } else { - result = updateOverspeedState(deviceState, position, speedLimit); + result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); } Context.getDeviceManager().setDeviceState(deviceId, deviceState); diff --git a/src/org/traccar/geocoder/GeocodeXyzGeocoder.java b/src/org/traccar/geocoder/GeocodeXyzGeocoder.java new file mode 100644 index 000000000..aca360c3d --- /dev/null +++ b/src/org/traccar/geocoder/GeocodeXyzGeocoder.java @@ -0,0 +1,60 @@ +/* + * Copyright 2018 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.geocoder; + +import javax.json.JsonObject; + +public class GeocodeXyzGeocoder extends JsonGeocoder { + + private static String formatUrl(String key) { + String url = "https://geocode.xyz/%f,%f?geoit=JSON"; + if (key != null) { + url += "&key=" + key; + } + return url; + } + + public GeocodeXyzGeocoder(String key, int cacheSize, AddressFormat addressFormat) { + super(formatUrl(key), cacheSize, addressFormat); + } + + @Override + public Address parseAddress(JsonObject json) { + Address address = new Address(); + + if (json.containsKey("stnumber")) { + address.setHouse(json.getString("stnumber")); + } + if (json.containsKey("staddress")) { + address.setStreet(json.getString("staddress")); + } + if (json.containsKey("city")) { + address.setSettlement(json.getString("city")); + } + if (json.containsKey("region")) { + address.setState(json.getString("region")); + } + if (json.containsKey("prov")) { + address.setCountry(json.getString("prov")); + } + if (json.containsKey("postal")) { + address.setPostcode(json.getString("postal")); + } + + return address; + } + +} diff --git a/src/org/traccar/geocoder/JsonGeocoder.java b/src/org/traccar/geocoder/JsonGeocoder.java index 82a6ee604..36a3acb76 100644 --- a/src/org/traccar/geocoder/JsonGeocoder.java +++ b/src/org/traccar/geocoder/JsonGeocoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,21 +15,17 @@ */ package org.traccar.geocoder; -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; import org.traccar.Context; import org.traccar.helper.Log; -import javax.json.Json; import javax.json.JsonObject; -import javax.json.JsonReader; - -import java.io.IOException; +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.InvocationCallback; import java.util.AbstractMap; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import java.util.concurrent.ExecutionException; public abstract class JsonGeocoder implements Geocoder { @@ -51,23 +47,23 @@ public abstract class JsonGeocoder implements Geocoder { } } - private String handleResponse(double latitude, double longitude, Response response, - ReverseGeocoderCallback callback) throws IOException { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - Address address = parseAddress(reader.readObject()); - if (address != null) { - String formattedAddress = addressFormat.format(address); - if (cache != null) { - cache.put(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude), formattedAddress); - } - if (callback != null) { - callback.onSuccess(formattedAddress); - } - return formattedAddress; + private String handleResponse( + double latitude, double longitude, JsonObject json, ReverseGeocoderCallback callback) { + + Address address = parseAddress(json); + if (address != null) { + String formattedAddress = addressFormat.format(address); + if (cache != null) { + cache.put(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude), formattedAddress); + } + if (callback != null) { + callback.onSuccess(formattedAddress); + } + return formattedAddress; + } else { + if (callback != null) { + callback.onFailure(new GeocoderException("Empty address")); } else { - if (callback != null) { - callback.onFailure(new GeocoderException("Empty address")); - } Log.warning("Empty address"); } } @@ -88,26 +84,25 @@ public abstract class JsonGeocoder implements Geocoder { } } + Invocation.Builder request = Context.getClient().target(String.format(url, latitude, longitude)).request(); + if (callback != null) { - Context.getAsyncHttpClient().prepareGet(String.format(url, latitude, longitude)) - .execute(new AsyncCompletionHandler() { + request.async().get(new InvocationCallback<JsonObject>() { @Override - public Object onCompleted(Response response) throws Exception { - return handleResponse(latitude, longitude, response, callback); + public void completed(JsonObject json) { + handleResponse(latitude, longitude, json, callback); } @Override - public void onThrowable(Throwable t) { - callback.onFailure(t); + public void failed(Throwable throwable) { + callback.onFailure(throwable); } }); } else { try { - Response response = Context.getAsyncHttpClient() - .prepareGet(String.format(url, latitude, longitude)).execute().get(); - return handleResponse(latitude, longitude, response, null); - } catch (InterruptedException | ExecutionException | IOException error) { - Log.warning("Geocoding failed", error); + return handleResponse(latitude, longitude, request.get(JsonObject.class), null); + } catch (ClientErrorException e) { + Log.warning(e); } } return null; diff --git a/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index d6e45b550..768aaf6a2 100644 --- a/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,15 +15,12 @@ */ package org.traccar.geolocation; -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; -import javax.json.Json; import javax.json.JsonObject; -import javax.json.JsonReader; +import javax.ws.rs.client.InvocationCallback; public class OpenCellIdGeolocationProvider implements GeolocationProvider { @@ -45,25 +42,21 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { String request = String.format(url, cellTower.getMobileCountryCode(), cellTower.getMobileNetworkCode(), cellTower.getLocationAreaCode(), cellTower.getCellId()); - Context.getAsyncHttpClient().prepareGet(request).execute(new AsyncCompletionHandler() { + Context.getClient().target(request).request().async().get(new InvocationCallback<JsonObject>() { @Override - public Object onCompleted(Response response) throws Exception { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - JsonObject json = reader.readObject(); - if (json.containsKey("lat") && json.containsKey("lon")) { - callback.onSuccess( - json.getJsonNumber("lat").doubleValue(), - json.getJsonNumber("lon").doubleValue(), 0); - } else { - callback.onFailure(new GeolocationException("Coordinates are missing")); - } + public void completed(JsonObject json) { + if (json.containsKey("lat") && json.containsKey("lon")) { + callback.onSuccess( + json.getJsonNumber("lat").doubleValue(), + json.getJsonNumber("lon").doubleValue(), 0); + } else { + callback.onFailure(new GeolocationException("Coordinates are missing")); } - return null; } @Override - public void onThrowable(Throwable t) { - callback.onFailure(t); + public void failed(Throwable throwable) { + callback.onFailure(throwable); } }); diff --git a/src/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/org/traccar/geolocation/UniversalGeolocationProvider.java index 6416b2633..f71620d8a 100644 --- a/src/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,17 +15,13 @@ */ package org.traccar.geolocation; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; import org.traccar.Context; import org.traccar.model.Network; -import javax.json.Json; import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; +import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { @@ -37,38 +33,26 @@ public class UniversalGeolocationProvider implements GeolocationProvider { @Override public void getLocation(Network network, final LocationProviderCallback callback) { - try { - String request = Context.getObjectMapper().writeValueAsString(network); - Context.getAsyncHttpClient().preparePost(url) - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(request.length())) - .setBody(request).execute(new AsyncCompletionHandler() { - @Override - public Object onCompleted(Response response) throws Exception { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - JsonObject json = reader.readObject(); - if (json.containsKey("error")) { - callback.onFailure( - new GeolocationException(json.getJsonObject("error").getString("message"))); - } else { - JsonObject location = json.getJsonObject("location"); - callback.onSuccess( - location.getJsonNumber("lat").doubleValue(), - location.getJsonNumber("lng").doubleValue(), - json.getJsonNumber("accuracy").doubleValue()); - } - } - return null; + AsyncInvoker invoker = Context.getClient().target(url).request().async(); + invoker.post(Entity.json(network), new InvocationCallback<JsonObject>() { + @Override + public void completed(JsonObject json) { + if (json.containsKey("error")) { + callback.onFailure(new GeolocationException(json.getJsonObject("error").getString("message"))); + } else { + JsonObject location = json.getJsonObject("location"); + callback.onSuccess( + location.getJsonNumber("lat").doubleValue(), + location.getJsonNumber("lng").doubleValue(), + json.getJsonNumber("accuracy").doubleValue()); } + } - @Override - public void onThrowable(Throwable t) { - callback.onFailure(t); - } - }); - } catch (JsonProcessingException e) { - callback.onFailure(e); - } + @Override + public void failed(Throwable throwable) { + callback.onFailure(throwable); + } + }); } } diff --git a/src/org/traccar/geolocation/UnwiredGeolocationProvider.java b/src/org/traccar/geolocation/UnwiredGeolocationProvider.java index dcc5a4e7a..963bcb688 100644 --- a/src/org/traccar/geolocation/UnwiredGeolocationProvider.java +++ b/src/org/traccar/geolocation/UnwiredGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -17,21 +17,16 @@ package org.traccar.geolocation; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.WifiAccessPoint; -import javax.json.Json; import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; import java.util.Collection; public class UnwiredGeolocationProvider implements GeolocationProvider { @@ -90,39 +85,27 @@ public class UnwiredGeolocationProvider implements GeolocationProvider { @Override public void getLocation(Network network, final LocationProviderCallback callback) { - try { - ObjectNode json = objectMapper.valueToTree(network); - json.put("token", key); - String request = objectMapper.writeValueAsString(json); - Context.getAsyncHttpClient().preparePost(url) - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(request.length())) - .setBody(request).execute(new AsyncCompletionHandler() { - @Override - public Object onCompleted(Response response) throws Exception { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - JsonObject json = reader.readObject(); - if (json.getString("status").equals("error")) { - callback.onFailure( - new GeolocationException(json.getString("message"))); - } else { - callback.onSuccess( - json.getJsonNumber("lat").doubleValue(), - json.getJsonNumber("lon").doubleValue(), - json.getJsonNumber("accuracy").doubleValue()); - } - } - return null; - } + ObjectNode json = objectMapper.valueToTree(network); + json.put("token", key); - @Override - public void onThrowable(Throwable t) { - callback.onFailure(t); + Context.getClient().target(url).request().async().post(Entity.json(json), new InvocationCallback<JsonObject>() { + @Override + public void completed(JsonObject json) { + if (json.getString("status").equals("error")) { + callback.onFailure(new GeolocationException(json.getString("message"))); + } else { + callback.onSuccess( + json.getJsonNumber("lat").doubleValue(), + json.getJsonNumber("lon").doubleValue(), + json.getJsonNumber("accuracy").doubleValue()); } - }); - } catch (JsonProcessingException e) { - callback.onFailure(e); - } + } + + @Override + public void failed(Throwable throwable) { + callback.onFailure(throwable); + } + }); } } diff --git a/src/org/traccar/helper/BcdUtil.java b/src/org/traccar/helper/BcdUtil.java index 495f94104..c87529e32 100644 --- a/src/org/traccar/helper/BcdUtil.java +++ b/src/org/traccar/helper/BcdUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,14 +15,14 @@ */ package org.traccar.helper; -import org.jboss.netty.buffer.ChannelBuffer; +import io.netty.buffer.ByteBuf; public final class BcdUtil { private BcdUtil() { } - public static int readInteger(ChannelBuffer buf, int digits) { + public static int readInteger(ByteBuf buf, int digits) { int result = 0; for (int i = 0; i < digits / 2; i++) { @@ -42,7 +42,7 @@ public final class BcdUtil { return result; } - public static double readCoordinate(ChannelBuffer buf) { + public static double readCoordinate(ByteBuf buf) { int b1 = buf.readUnsignedByte(); int b2 = buf.readUnsignedByte(); int b3 = buf.readUnsignedByte(); diff --git a/src/org/traccar/helper/BitBuffer.java b/src/org/traccar/helper/BitBuffer.java index ac307efdf..f30a4557b 100644 --- a/src/org/traccar/helper/BitBuffer.java +++ b/src/org/traccar/helper/BitBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,12 @@ */ package org.traccar.helper; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; public class BitBuffer { - private final ChannelBuffer buffer; + private final ByteBuf buffer; private int writeByte; private int writeCount; @@ -29,10 +29,10 @@ public class BitBuffer { private int readCount; public BitBuffer() { - buffer = ChannelBuffers.dynamicBuffer(); + buffer = Unpooled.buffer(); } - public BitBuffer(ChannelBuffer buffer) { + public BitBuffer(ByteBuf buffer) { this.buffer = buffer; } diff --git a/src/org/traccar/helper/BufferUtil.java b/src/org/traccar/helper/BufferUtil.java new file mode 100644 index 000000000..5606dba8a --- /dev/null +++ b/src/org/traccar/helper/BufferUtil.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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.helper; + +import java.nio.charset.StandardCharsets; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; + +public final class BufferUtil { + + private BufferUtil() { + } + + public static int indexOf(String needle, ByteBuf haystack) { + ByteBuf needleBuffer = Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII)); + try { + return ByteBufUtil.indexOf(needleBuffer, haystack); + } finally { + needleBuffer.release(); + } + } + + public static int indexOf(String needle, ByteBuf haystack, int startIndex, int endIndex) { + haystack = Unpooled.wrappedBuffer(haystack); + haystack.readerIndex(startIndex); + haystack.writerIndex(endIndex); + return indexOf(needle, haystack); + } + +} diff --git a/src/org/traccar/helper/Checksum.java b/src/org/traccar/helper/Checksum.java index 43ba6a689..5aed84bf8 100644 --- a/src/org/traccar/helper/Checksum.java +++ b/src/org/traccar/helper/Checksum.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -24,163 +24,109 @@ public final class Checksum { private Checksum() { } - private static final int[] CRC16_CCITT_TABLE_REVERSE = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 - }; - - private static final int[] CRC16_CCITT_TABLE = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 - }; - - private static final int[] CRC16_IBM_TABLE = { - 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, - 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, - 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, - 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, - 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, - 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, - 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, - 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, - 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, - 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, - 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, - 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, - 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, - 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, - 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, - 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, - 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, - 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, - 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, - 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, - 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, - 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, - 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, - 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, - 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, - 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, - 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, - 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, - 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, - 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, - 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, - 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, - }; - - // More info: http://reveng.sourceforge.net/crc-catalogue/16.htm - public static final String CRC16_IBM = "IBM"; - public static final String CRC16_MODBUS = "MODBUS"; - public static final String CRC16_X25 = "X-25"; - public static final String CRC16_CCITT_FALSE = "CCITT-FALSE"; - public static final String CRC16_KERMIT = "KERMIT"; - public static final String CRC16_XMODEM = "XMODEM"; - public static final String CRC16_AUG_CCITT = "AUG-CCITT"; - public static final String CRC16_GENIBUS = "GENIBUS"; - public static final String CRC16_MCRF4XX = "MCRF4XX"; - - private static int crc16Unreflected(ByteBuffer buf, int crcIn, int[] table) { - int crc16 = crcIn; - while (buf.hasRemaining()) { - crc16 = table[((crc16 >> 8) ^ buf.get()) & 0xff] ^ (crc16 << 8); + public static class Algorithm { + + private int poly; + private int init; + private boolean refIn; + private boolean refOut; + private int xorOut; + private int[] table; + + public Algorithm(int bits, int poly, int init, boolean refIn, boolean refOut, int xorOut) { + this.poly = poly; + this.init = init; + this.refIn = refIn; + this.refOut = refOut; + this.xorOut = xorOut; + this.table = bits == 8 ? initTable8() : initTable16(); + } + + private int[] initTable8() { + int[] table = new int[256]; + int crc; + for (int i = 0; i < 256; i++) { + crc = i; + for (int j = 0; j < 8; j++) { + boolean bit = (crc & 0x80) != 0; + crc <<= 1; + if (bit) { + crc ^= poly; + } + } + table[i] = crc & 0xFF; + } + return table; + } + + private int[] initTable16() { + int[] table = new int[256]; + int crc; + for (int i = 0; i < 256; i++) { + crc = i << 8; + for (int j = 0; j < 8; j++) { + boolean bit = (crc & 0x8000) != 0; + crc <<= 1; + if (bit) { + crc ^= poly; + } + } + table[i] = crc & 0xFFFF; + } + return table; + } + + } + + private static int reverse(int value, int bits) { + int result = 0; + for (int i = 0; i < bits; i++) { + result = (result << 1) | (value & 1); + value >>= 1; } - return crc16 & 0xFFFF; + return result; } - private static int crc16Reflected(ByteBuffer buf, int crcIn, int[] table) { - int crc16 = crcIn; + public static int crc8(Algorithm algorithm, ByteBuffer buf) { + int crc = algorithm.init; while (buf.hasRemaining()) { - crc16 = table[(crc16 ^ buf.get()) & 0xff] ^ (crc16 >> 8); + int b = buf.get() & 0xFF; + if (algorithm.refIn) { + b = reverse(b, 8); + } + crc = algorithm.table[(crc & 0xFF) ^ b]; + } + if (algorithm.refOut) { + crc = reverse(crc, 8); } - return crc16 & 0xFFFF; + return (crc ^ algorithm.xorOut) & 0xFF; } - public static int crc16(String type, ByteBuffer buf) { - switch (type) { - case CRC16_IBM: - return crc16Reflected(buf, 0, CRC16_IBM_TABLE); - case CRC16_MODBUS: - return crc16Reflected(buf, 0xFFFF, CRC16_IBM_TABLE); - case CRC16_X25: - return crc16Reflected(buf, 0xFFFF, CRC16_CCITT_TABLE_REVERSE) ^ 0xFFFF; - case CRC16_CCITT_FALSE: - return crc16Unreflected(buf, 0xFFFF, CRC16_CCITT_TABLE); - case CRC16_KERMIT: - return crc16Reflected(buf, 0, CRC16_CCITT_TABLE_REVERSE); - case CRC16_XMODEM: - return crc16Unreflected(buf, 0, CRC16_CCITT_TABLE); - case CRC16_AUG_CCITT: - return crc16Unreflected(buf, 0x1d0f, CRC16_CCITT_TABLE); - case CRC16_GENIBUS: - return crc16Unreflected(buf, 0xFFFF, CRC16_CCITT_TABLE) ^ 0xFFFF; - case CRC16_MCRF4XX: - return crc16Reflected(buf, 0xFFFF, CRC16_CCITT_TABLE_REVERSE); - default: - throw new UnsupportedOperationException(type); + public static int crc16(Algorithm algorithm, ByteBuffer buf) { + int crc = algorithm.init; + while (buf.hasRemaining()) { + int b = buf.get() & 0xFF; + if (algorithm.refIn) { + b = reverse(b, 8); + } + crc = (crc << 8) ^ algorithm.table[((crc >> 8) & 0xFF) ^ b]; + } + if (algorithm.refOut) { + crc = reverse(crc, 16); } + return (crc ^ algorithm.xorOut) & 0xFFFF; } + public static final Algorithm CRC8_EGTS = new Algorithm(8, 0x31, 0xFF, false, false, 0x00); + public static final Algorithm CRC8_ROHC = new Algorithm(8, 0x07, 0xFF, true, true, 0x00); + + public static final Algorithm CRC16_IBM = new Algorithm(16, 0x8005, 0x0000, true, true, 0x0000); + public static final Algorithm CRC16_X25 = new Algorithm(16, 0x1021, 0xFFFF, true, true, 0xFFFF); + public static final Algorithm CRC16_MODBUS = new Algorithm(16, 0x8005, 0xFFFF, true, true, 0x0000); + public static final Algorithm CRC16_CCITT_FALSE = new Algorithm(16, 0x1021, 0xFFFF, false, false, 0x0000); + public static final Algorithm CRC16_KERMIT = new Algorithm(16, 0x1021, 0x0000, true, true, 0x0000); + public static final Algorithm CRC16_XMODEM = new Algorithm(16, 0x1021, 0x0000, false, false, 0x0000); + public static int crc32(ByteBuffer buf) { CRC32 checksum = new CRC32(); while (buf.hasRemaining()) { diff --git a/src/org/traccar/helper/Log.java b/src/org/traccar/helper/Log.java index d74246a64..a22e4bde2 100644 --- a/src/org/traccar/helper/Log.java +++ b/src/org/traccar/helper/Log.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -23,9 +23,6 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.varia.NullAppender; -import org.jboss.netty.logging.AbstractInternalLogger; -import org.jboss.netty.logging.InternalLogger; -import org.jboss.netty.logging.InternalLoggerFactory; import org.traccar.Config; import java.io.IOException; @@ -67,14 +64,6 @@ public final class Log { logger.addAppender(appender); logger.setLevel(Level.toLevel(config.getString("logger.level"), Level.ALL)); - // Workaround for "Bug 745866 - (EDG-45) Possible netty logging config problem" - InternalLoggerFactory.setDefaultFactory(new InternalLoggerFactory() { - @Override - public InternalLogger newInstance(String string) { - return new NettyInternalLogger(); - } - }); - Log.logSystemInfo(); Log.info("Version: " + getAppVersion()); } @@ -200,69 +189,4 @@ public final class Log { return s.toString(); } - /** - * Netty logger implementation - */ - private static class NettyInternalLogger extends AbstractInternalLogger { - - @Override - public boolean isDebugEnabled() { - return false; - } - - @Override - public boolean isInfoEnabled() { - return false; - } - - @Override - public boolean isWarnEnabled() { - return true; - } - - @Override - public boolean isErrorEnabled() { - return true; - } - - @Override - public void debug(String string) { - debug(string, null); - } - - @Override - public void debug(String string, Throwable thrwbl) { - } - - @Override - public void info(String string) { - info(string, null); - } - - @Override - public void info(String string, Throwable thrwbl) { - } - - @Override - public void warn(String string) { - warn(string, null); - } - - @Override - public void warn(String string, Throwable thrwbl) { - getLogger().warn("netty warning: " + string); - } - - @Override - public void error(String string) { - error(string, null); - } - - @Override - public void error(String string, Throwable thrwbl) { - getLogger().error("netty error: " + string); - } - - } - } diff --git a/src/org/traccar/helper/StringFinder.java b/src/org/traccar/helper/StringFinder.java deleted file mode 100644 index 2fa0aa9a4..000000000 --- a/src/org/traccar/helper/StringFinder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2015 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.helper; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBufferIndexFinder; - -import java.nio.charset.StandardCharsets; - -public class StringFinder implements ChannelBufferIndexFinder { - - private String string; - - public StringFinder(String string) { - this.string = string; - } - - @Override - public boolean find(ChannelBuffer buffer, int guessedIndex) { - - if (buffer.writerIndex() - guessedIndex < string.length()) { - return false; - } - - return string.equals(buffer.toString(guessedIndex, string.length(), StandardCharsets.US_ASCII)); - } - -} diff --git a/src/org/traccar/helper/UnitsConverter.java b/src/org/traccar/helper/UnitsConverter.java index 56d15e4e7..3dd435df4 100644 --- a/src/org/traccar/helper/UnitsConverter.java +++ b/src/org/traccar/helper/UnitsConverter.java @@ -23,6 +23,8 @@ public final class UnitsConverter { private static final double KNOTS_TO_CPS_RATIO = 0.0194384449; private static final double METERS_TO_FEET_RATIO = 0.3048; private static final double METERS_TO_MILE_RATIO = 1609.34; + private static final long MILLISECONDS_TO_HOURS_RATIO = 3600000; + private static final long MILLISECONDS_TO_MINUTES_RATIO = 60000; private UnitsConverter() { } @@ -71,4 +73,16 @@ public final class UnitsConverter { return value * METERS_TO_MILE_RATIO; } + public static long msFromHours(long value) { + return value * MILLISECONDS_TO_HOURS_RATIO; + } + + public static long msFromHours(double value) { + return (long) (value * MILLISECONDS_TO_HOURS_RATIO); + } + + public static long msFromMinutes(long value) { + return value * MILLISECONDS_TO_MINUTES_RATIO; + } + } diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java index f2d0ff614..75d6726ee 100644 --- a/src/org/traccar/model/DeviceState.java +++ b/src/org/traccar/model/DeviceState.java @@ -58,4 +58,14 @@ public class DeviceState { return overspeedPosition; } + private long overspeedGeofenceId; + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + } diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java index 465afeb35..ee7fcc679 100644 --- a/src/org/traccar/model/Event.java +++ b/src/org/traccar/model/Event.java @@ -91,4 +91,14 @@ public class Event extends Message { this.geofenceId = geofenceId; } + private long maintenanceId = 0; + + public long getMaintenanceId() { + return maintenanceId; + } + + public void setMaintenanceId(long maintenanceId) { + this.maintenanceId = maintenanceId; + } + } diff --git a/src/org/traccar/model/Geofence.java b/src/org/traccar/model/Geofence.java index 7042325dc..8560d22e9 100644 --- a/src/org/traccar/model/Geofence.java +++ b/src/org/traccar/model/Geofence.java @@ -65,7 +65,9 @@ public class Geofence extends ScheduledModel { } else if (area.startsWith("POLYGON")) { geometry = new GeofencePolygon(area); } else if (area.startsWith("LINESTRING")) { - geometry = new GeofencePolyline(area, Context.getConfig().getDouble("geofence.polylineDistance", 25)); + final double distance = getDouble("polylineDistance"); + geometry = new GeofencePolyline(area, distance > 0 ? distance + : Context.getConfig().getDouble("geofence.polylineDistance", 25)); } else { throw new ParseException("Unknown geometry type", 0); } diff --git a/src/org/traccar/model/Maintenance.java b/src/org/traccar/model/Maintenance.java new file mode 100644 index 000000000..73f67ea96 --- /dev/null +++ b/src/org/traccar/model/Maintenance.java @@ -0,0 +1,61 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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.model; + +public class Maintenance extends ExtendedModel { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + private double start; + + public double getStart() { + return start; + } + + public void setStart(double start) { + this.start = start; + } + + private double period; + + public double getPeriod() { + return period; + } + + public void setPeriod(double period) { + this.period = period; + } + +} diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 49e3231c3..4b327cbd2 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -39,6 +39,7 @@ public class Position extends Message { public static final String KEY_ODOMETER_TRIP = "tripOdometer"; // meters public static final String KEY_HOURS = "hours"; public static final String KEY_STEPS = "steps"; + public static final String KEY_HEART_RATE = "heartRate"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_IMAGE = "image"; @@ -51,6 +52,7 @@ public class Position extends Message { public static final String KEY_BATTERY = "battery"; // volts public static final String KEY_BATTERY_LEVEL = "batteryLevel"; // percentage public static final String KEY_FUEL_LEVEL = "fuel"; // liters + public static final String KEY_FUEL_USED = "fuelUsed"; // liters public static final String KEY_FUEL_CONSUMPTION = "fuelConsumption"; // liters/hour public static final String KEY_VERSION_FW = "versionFw"; @@ -58,6 +60,7 @@ public class Position extends Message { public static final String KEY_TYPE = "type"; public static final String KEY_IGNITION = "ignition"; public static final String KEY_FLAGS = "flags"; + public static final String KEY_ANTENNA = "antenna"; public static final String KEY_CHARGE = "charge"; public static final String KEY_IP = "ip"; public static final String KEY_ARCHIVE = "archive"; @@ -109,6 +112,8 @@ public class Position extends Message { public static final String ALARM_POWER_OFF = "powerOff"; public static final String ALARM_POWER_ON = "powerOn"; public static final String ALARM_DOOR = "door"; + public static final String ALARM_LOCK = "lock"; + public static final String ALARM_UNLOCK = "unlock"; public static final String ALARM_GEOFENCE = "geofence"; public static final String ALARM_GEOFENCE_ENTER = "geofenceEnter"; public static final String ALARM_GEOFENCE_EXIT = "geofenceExit"; @@ -116,9 +121,11 @@ public class Position extends Message { public static final String ALARM_ACCIDENT = "accident"; public static final String ALARM_TOW = "tow"; public static final String ALARM_IDLE = "idle"; + public static final String ALARM_HIGH_RPM = "highRpm"; public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BRAKING = "hardBraking"; public static final String ALARM_CORNERING = "hardCornering"; + public static final String ALARM_LANE_CHANGE = "laneChange"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; public static final String ALARM_POWER_RESTORED = "powerRestored"; @@ -128,7 +135,7 @@ public class Position extends Message { public static final String ALARM_SHOCK = "shock"; public static final String ALARM_BONNET = "bonnet"; public static final String ALARM_FOOT_BRAKE = "footBrake"; - public static final String ALARM_OIL_LEAK = "oilLeak"; + public static final String ALARM_FUEL_LEAK = "fuelLeak"; public static final String ALARM_TAMPERING = "tampering"; public static final String ALARM_REMOVING = "removing"; diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index 1a131a4e8..976b6aac0 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -75,14 +75,14 @@ public class User extends ExtendedModel { this.readonly = readonly; } - private boolean admin; + private boolean administrator; - public boolean getAdmin() { - return admin; + public boolean getAdministrator() { + return administrator; } - public void setAdmin(boolean admin) { - this.admin = admin; + public void setAdministrator(boolean administrator) { + this.administrator = administrator; } private String map; @@ -203,7 +203,7 @@ public class User extends ExtendedModel { public void setToken(String token) { if (token != null && !token.isEmpty()) { - if (!token.matches("^[a-zA-Z0-9]{16,}$")) { + if (!token.matches("^[a-zA-Z0-9-]{16,}$")) { throw new IllegalArgumentException("Illegal token"); } this.token = token; diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index b13f8fe43..b8990d84f 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -15,25 +15,21 @@ */ package org.traccar.notification; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; -import java.util.Collections; -import java.util.List; - +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.traccar.Context; -import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; import org.traccar.model.Position; -import java.nio.charset.StandardCharsets; +import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Invocation; import java.util.HashMap; import java.util.Map; import java.util.Set; -import com.ning.http.client.FluentCaseInsensitiveStringsMap; - public abstract class EventForwarder { private final String url; @@ -48,41 +44,34 @@ public abstract class EventForwarder { private static final String KEY_EVENT = "event"; private static final String KEY_GEOFENCE = "geofence"; private static final String KEY_DEVICE = "device"; + private static final String KEY_MAINTENANCE = "maintenance"; private static final String KEY_USERS = "users"; public final void forwardEvent(Event event, Position position, Set<Long> users) { - BoundRequestBuilder requestBuilder = Context.getAsyncHttpClient().preparePost(url); - requestBuilder.setBodyEncoding(StandardCharsets.UTF_8.name()); - - requestBuilder.addHeader("Content-Type", getContentType()); + Invocation.Builder requestBuilder = Context.getClient().target(url).request(); if (header != null && !header.isEmpty()) { - FluentCaseInsensitiveStringsMap params = new FluentCaseInsensitiveStringsMap(); - params.putAll(splitIntoKeyValues(header, ":")); - requestBuilder.setHeaders(params); + for (Map.Entry<String, String> entry : splitKeyValues(header, ":").entries()) { + requestBuilder = requestBuilder.header(entry.getKey(), entry.getValue()); + } } - setContent(event, position, users, requestBuilder); - requestBuilder.execute(); + executeRequest(event, position, users, requestBuilder.async()); } - protected Map<String, List<String>> splitIntoKeyValues(String params, String separator) { - - String[] splitedLine; - Map<String, List<String>> paramsMap = new HashMap<>(); - String[] paramsLines = params.split("\\r?\\n"); - - for (String paramLine: paramsLines) { - splitedLine = paramLine.split(separator, 2); - if (splitedLine.length == 2) { - paramsMap.put(splitedLine[0].trim(), Collections.singletonList(splitedLine[1].trim())); + protected MultiValuedMap<String, String> splitKeyValues(String params, String separator) { + MultiValuedMap<String, String> data = new ArrayListValuedHashMap<>(); + for (String line: params.split("\\r?\\n")) { + String[] values = line.split(separator, 2); + if (values.length == 2) { + data.put(values[0].trim(), values[1].trim()); } } - return paramsMap; + return data; } - protected String prepareJsonPayload(Event event, Position position, Set<Long> users) { + protected Map<String, Object> preparePayload(Event event, Position position, Set<Long> users) { Map<String, Object> data = new HashMap<>(); data.put(KEY_EVENT, event); if (position != null) { @@ -98,17 +87,17 @@ public abstract class EventForwarder { data.put(KEY_GEOFENCE, geofence); } } - data.put(KEY_USERS, Context.getUsersManager().getItems(users)); - try { - return Context.getObjectMapper().writeValueAsString(data); - } catch (JsonProcessingException e) { - Log.warning(e); - return null; + if (event.getMaintenanceId() != 0) { + Maintenance maintenance = Context.getMaintenancesManager().getById(event.getMaintenanceId()); + if (maintenance != null) { + data.put(KEY_MAINTENANCE, maintenance); + } } + data.put(KEY_USERS, Context.getUsersManager().getItems(users)); + return data; } - protected abstract String getContentType(); - protected abstract void setContent( - Event event, Position position, Set<Long> users, BoundRequestBuilder requestBuilder); + protected abstract void executeRequest( + Event event, Position position, Set<Long> users, AsyncInvoker invoker); } diff --git a/src/org/traccar/notification/JsonTypeEventForwarder.java b/src/org/traccar/notification/JsonTypeEventForwarder.java index 27ef61af1..fcafb964a 100644 --- a/src/org/traccar/notification/JsonTypeEventForwarder.java +++ b/src/org/traccar/notification/JsonTypeEventForwarder.java @@ -5,18 +5,14 @@ import java.util.Set; import org.traccar.model.Event;
import org.traccar.model.Position;
-import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
+import javax.ws.rs.client.AsyncInvoker;
+import javax.ws.rs.client.Entity;
public class JsonTypeEventForwarder extends EventForwarder {
@Override
- protected String getContentType() {
- return "application/json; charset=utf-8";
- }
-
- @Override
- protected void setContent(Event event, Position position, Set<Long> users, BoundRequestBuilder requestBuilder) {
- requestBuilder.setBody(prepareJsonPayload(event, position, users));
+ protected void executeRequest(Event event, Position position, Set<Long> users, AsyncInvoker invoker) {
+ invoker.post(Entity.json(preparePayload(event, position, users)));
}
}
diff --git a/src/org/traccar/notification/MultiPartEventForwarder.java b/src/org/traccar/notification/MultiPartEventForwarder.java deleted file mode 100644 index 6227c66cc..000000000 --- a/src/org/traccar/notification/MultiPartEventForwarder.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.traccar.notification; - -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import org.traccar.Context; -import org.traccar.model.Event; -import org.traccar.model.Position; - -import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; -import com.ning.http.client.multipart.StringPart; - -public class MultiPartEventForwarder extends EventForwarder { - - private final String payloadParamName; - private final String additionalParams; - - public MultiPartEventForwarder() { - payloadParamName = Context.getConfig().getString("event.forward.paramMode.payloadParamName", "payload"); - additionalParams = Context.getConfig().getString("event.forward.paramMode.additionalParams"); - } - - @Override - protected String getContentType() { - return "multipart/form-data"; - } - - @Override - protected void setContent(Event event, Position position, Set<Long> users, BoundRequestBuilder requestBuilder) { - - if (additionalParams != null && !additionalParams.isEmpty()) { - Map<String, List<String>> paramsToAdd = splitIntoKeyValues(additionalParams, "="); - - for (Entry<String, List<String>> param : paramsToAdd.entrySet()) { - for (String singleParamValue : param.getValue()) { - requestBuilder.addBodyPart(new StringPart(param.getKey(), singleParamValue, null, - StandardCharsets.UTF_8)); - } - } - } - requestBuilder.addBodyPart(new StringPart(payloadParamName, - prepareJsonPayload(event, position, users), "application/json", StandardCharsets.UTF_8)); - } -} diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java index d1f6c3903..ddc35227e 100644 --- a/src/org/traccar/notification/NotificationFormatter.java +++ b/src/org/traccar/notification/NotificationFormatter.java @@ -1,6 +1,6 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,9 @@ public final class NotificationFormatter { if (event.getGeofenceId() != 0) { velocityContext.put("geofence", Context.getGeofenceManager().getById(event.getGeofenceId())); } + if (event.getMaintenanceId() != 0) { + velocityContext.put("maintenance", Context.getMaintenancesManager().getById(event.getMaintenanceId())); + } String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId)); diff --git a/src/org/traccar/processing/ComputedAttributesHandler.java b/src/org/traccar/processing/ComputedAttributesHandler.java index b37db05bf..a4edcc460 100644 --- a/src/org/traccar/processing/ComputedAttributesHandler.java +++ b/src/org/traccar/processing/ComputedAttributesHandler.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import io.netty.channel.ChannelHandler; import org.apache.commons.jexl2.JexlEngine; import org.apache.commons.jexl2.JexlException; import org.apache.commons.jexl2.MapContext; @@ -35,6 +36,7 @@ import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; +@ChannelHandler.Sharable public class ComputedAttributesHandler extends BaseDataHandler { private JexlEngine engine; diff --git a/src/org/traccar/processing/CopyAttributesHandler.java b/src/org/traccar/processing/CopyAttributesHandler.java index 9fbcfa73f..bdd73b141 100644 --- a/src/org/traccar/processing/CopyAttributesHandler.java +++ b/src/org/traccar/processing/CopyAttributesHandler.java @@ -16,10 +16,12 @@ */ package org.traccar.processing; +import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.Context; import org.traccar.model.Position; +@ChannelHandler.Sharable public class CopyAttributesHandler extends BaseDataHandler { private Position getLastPosition(long deviceId) { diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java index 4d2cbe7b3..994661af2 100644 --- a/src/org/traccar/protocol/AdmProtocol.java +++ b/src/org/traccar/protocol/AdmProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,17 +36,16 @@ public class AdmProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 1, -3, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 1, -3, 0, true)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new AdmProtocolEncoder()); pipeline.addLast("objectDecoder", new AdmProtocolDecoder(AdmProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index 4ae16017a..4c41d29cd 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -38,7 +38,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PHOTO = 0x0A; public static final int MSG_ADM5 = 0x01; - private Position decodeData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { + private Position decodeData(Channel channel, SocketAddress remoteAddress, ByteBuf buf, int type) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -50,25 +50,25 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); - int status = buf.readUnsignedShort(); + int status = buf.readUnsignedShortLE(); position.set(Position.KEY_STATUS, status); position.setValid(!BitUtil.check(status, 5)); - position.setLatitude(buf.readFloat()); - position.setLongitude(buf.readFloat()); - position.setCourse(buf.readUnsignedShort() * 0.1); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setLatitude(buf.readFloatLE()); + position.setLongitude(buf.readFloatLE()); + position.setCourse(buf.readUnsignedShortLE() * 0.1); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte() * 0.1); - position.setAltitude(buf.readUnsignedShort()); + position.setAltitude(buf.readUnsignedShortLE()); position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f); - position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); if (BitUtil.check(type, 2)) { buf.readUnsignedByte(); // vib @@ -84,19 +84,19 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(type, 3)) { for (int i = 1; i <= 6; i++) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort() * 0.001); + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE() * 0.001); } } if (BitUtil.check(type, 4)) { for (int i = 1; i <= 2; i++) { - position.set(Position.PREFIX_COUNT + i, buf.readUnsignedInt()); + position.set(Position.PREFIX_COUNT + i, buf.readUnsignedIntLE()); } } if (BitUtil.check(type, 5)) { for (int i = 1; i <= 3; i++) { - buf.readUnsignedShort(); // fuel level + buf.readUnsignedShortLE(); // fuel level } for (int i = 1; i <= 3; i++) { position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte()); @@ -108,7 +108,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(type, 7)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); } return position; @@ -117,7 +117,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { return null; } - private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; @@ -132,22 +132,22 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { if (responseTextLength < 0) { responseTextLength = CMD_RESPONSE_SIZE - 3; } - position.set(Position.KEY_RESULT, buf.readBytes(responseTextLength).toString(StandardCharsets.UTF_8)); + position.set(Position.KEY_RESULT, buf.readSlice(responseTextLength).toString(StandardCharsets.UTF_8)); return position; } @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - buf.readUnsignedShort(); // device id + buf.readUnsignedShortLE(); // device id int size = buf.readUnsignedByte(); if (size != CMD_RESPONSE_SIZE) { int type = buf.readUnsignedByte(); if (type == MSG_IMEI) { - getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.UTF_8)); + getDeviceSession(channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.UTF_8)); } else { return decodeData(channel, remoteAddress, buf, type); } diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java index 8cbd8618d..bcbf8a2f1 100644 --- a/src/org/traccar/protocol/AdmProtocolEncoder.java +++ b/src/org/traccar/protocol/AdmProtocolEncoder.java @@ -39,4 +39,5 @@ public class AdmProtocolEncoder extends StringProtocolEncoder { return null; } + } diff --git a/src/org/traccar/protocol/AisProtocol.java b/src/org/traccar/protocol/AisProtocol.java index 4b2e1719e..ff81db45c 100644 --- a/src/org/traccar/protocol/AisProtocol.java +++ b/src/org/traccar/protocol/AisProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,10 +15,9 @@ */ 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 io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class AisProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new AisProtocolDecoder(AisProtocol.this)); } diff --git a/src/org/traccar/protocol/AisProtocolDecoder.java b/src/org/traccar/protocol/AisProtocolDecoder.java index 842260e98..7954ef5f9 100644 --- a/src/org/traccar/protocol/AisProtocolDecoder.java +++ b/src/org/traccar/protocol/AisProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitBuffer; diff --git a/src/org/traccar/protocol/AlematicsFrameDecoder.java b/src/org/traccar/protocol/AlematicsFrameDecoder.java index b8b3e3403..be7666657 100644 --- a/src/org/traccar/protocol/AlematicsFrameDecoder.java +++ b/src/org/traccar/protocol/AlematicsFrameDecoder.java @@ -15,10 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LineBasedFrameDecoder; +import org.traccar.NetworkMessage; public class AlematicsFrameDecoder extends LineBasedFrameDecoder { @@ -31,20 +31,20 @@ public class AlematicsFrameDecoder extends LineBasedFrameDecoder { // example of heartbeat: FA F8 00 07 00 03 15 AD 4E 78 3A D2 @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { return null; } if (buf.getUnsignedShort(buf.readerIndex()) == 0xFAF8) { - ChannelBuffer heartbeat = buf.readBytes(12); - if (channel != null) { - channel.write(heartbeat); + ByteBuf heartbeat = buf.readRetainedSlice(12); + if (ctx != null && ctx.channel() != null) { + ctx.channel().writeAndFlush(new NetworkMessage(heartbeat, ctx.channel().remoteAddress())); } } - return super.decode(ctx, channel, buf); + return super.decode(ctx, buf); } } diff --git a/src/org/traccar/protocol/AlematicsProtocol.java b/src/org/traccar/protocol/AlematicsProtocol.java index 241ce8bf9..a8bb124f9 100644 --- a/src/org/traccar/protocol/AlematicsProtocol.java +++ b/src/org/traccar/protocol/AlematicsProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class AlematicsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new AlematicsFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/org/traccar/protocol/AlematicsProtocolDecoder.java index b83081cc1..794588f5f 100644 --- a/src/org/traccar/protocol/AlematicsProtocolDecoder.java +++ b/src/org/traccar/protocol/AlematicsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/ApelProtocol.java b/src/org/traccar/protocol/ApelProtocol.java index 690b5ed99..6b18c2fb8 100644 --- a/src/org/traccar/protocol/ApelProtocol.java +++ b/src/org/traccar/protocol/ApelProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class ApelProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, 4, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast("objectDecoder", new ApelProtocolDecoder(ApelProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/ApelProtocolDecoder.java b/src/org/traccar/protocol/ApelProtocolDecoder.java index a107f7d6f..affbdedaf 100644 --- a/src/org/traccar/protocol/ApelProtocolDecoder.java +++ b/src/org/traccar/protocol/ApelProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,17 +15,17 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; @@ -66,24 +66,24 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { public static final short MSG_GPRS_COMMAND = 180; private void sendSimpleMessage(Channel channel, short type) { - ChannelBuffer request = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 8); - request.writeShort(type); - request.writeShort(0); - request.writeInt(Checksum.crc32(request.toByteBuffer(0, 4))); - channel.write(request); + ByteBuf request = Unpooled.buffer(8); + request.writeShortLE(type); + request.writeShortLE(0); + request.writeIntLE(Checksum.crc32(request.nioBuffer(0, 4))); + channel.writeAndFlush(new NetworkMessage(request, channel.remoteAddress())); } private void requestArchive(Channel channel) { if (lastIndex == 0) { lastIndex = newIndex; } else if (newIndex > lastIndex) { - ChannelBuffer request = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 14); - request.writeShort(MSG_REQUEST_LOG_RECORDS); - request.writeShort(6); - request.writeInt((int) lastIndex); - request.writeShort(512); - request.writeInt(Checksum.crc32(request.toByteBuffer(0, 10))); - channel.write(request); + ByteBuf request = Unpooled.buffer(14); + request.writeShortLE(MSG_REQUEST_LOG_RECORDS); + request.writeShortLE(6); + request.writeIntLE((int) lastIndex); + request.writeShortLE(512); + request.writeIntLE(Checksum.crc32(request.nioBuffer(0, 10))); + channel.writeAndFlush(new NetworkMessage(request, channel.remoteAddress())); } } @@ -91,11 +91,11 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; - int type = buf.readUnsignedShort(); + ByteBuf buf = (ByteBuf) msg; + int type = buf.readUnsignedShortLE(); boolean alarm = (type & 0x8000) != 0; type = type & 0x7FFF; - buf.readUnsignedShort(); // length + buf.readUnsignedShortLE(); // length if (alarm) { sendSimpleMessage(channel, MSG_ACK_ALARM); @@ -107,15 +107,15 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_TRACKER_ID_EXT) { - buf.readUnsignedInt(); // id - int length = buf.readUnsignedShort(); + buf.readUnsignedIntLE(); // id + int length = buf.readUnsignedShortLE(); buf.skipBytes(length); - length = buf.readUnsignedShort(); - getDeviceSession(channel, remoteAddress, buf.readBytes(length).toString(StandardCharsets.US_ASCII)); + length = buf.readUnsignedShortLE(); + getDeviceSession(channel, remoteAddress, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); } else if (type == MSG_LAST_LOG_INDEX) { - long index = buf.readUnsignedInt(); + long index = buf.readUnsignedIntLE(); if (index > 0) { newIndex = index; requestArchive(channel); @@ -132,7 +132,7 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { int recordCount = 1; if (type == MSG_LOG_RECORDS) { - recordCount = buf.readUnsignedShort(); + recordCount = buf.readUnsignedShortLE(); } for (int j = 0; j < recordCount; j++) { @@ -142,20 +142,20 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { int subtype = type; if (type == MSG_LOG_RECORDS) { position.set(Position.KEY_ARCHIVE, true); - lastIndex = buf.readUnsignedInt() + 1; + lastIndex = buf.readUnsignedIntLE() + 1; position.set(Position.KEY_INDEX, lastIndex); - subtype = buf.readUnsignedShort(); + subtype = buf.readUnsignedShortLE(); if (subtype != MSG_CURRENT_GPS_DATA && subtype != MSG_STATE_FULL_INFO_T104) { - buf.skipBytes(buf.readUnsignedShort()); + buf.skipBytes(buf.readUnsignedShortLE()); continue; } - buf.readUnsignedShort(); // length + buf.readUnsignedShortLE(); // length } - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.setLatitude(buf.readInt() * 180.0 / 0x7FFFFFFF); - position.setLongitude(buf.readInt() * 180.0 / 0x7FFFFFFF); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLatitude(buf.readIntLE() * 180.0 / 0x7FFFFFFF); + position.setLongitude(buf.readIntLE() * 180.0 / 0x7FFFFFFF); if (subtype == MSG_STATE_FULL_INFO_T104) { int speed = buf.readUnsignedByte(); @@ -163,36 +163,36 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(speed)); position.set(Position.KEY_HDOP, buf.readByte()); } else { - int speed = buf.readShort(); + int speed = buf.readShortLE(); position.setValid(speed != -1); position.setSpeed(UnitsConverter.knotsFromKph(speed * 0.01)); } - position.setCourse(buf.readShort() * 0.01); - position.setAltitude(buf.readShort()); + position.setCourse(buf.readShortLE() * 0.01); + position.setAltitude(buf.readShortLE()); if (subtype == MSG_STATE_FULL_INFO_T104) { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); position.set(Position.KEY_INPUT, buf.readUnsignedByte()); position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); for (int i = 1; i <= 8; i++) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE()); } - position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedInt()); - position.set(Position.PREFIX_COUNT + 2, buf.readUnsignedInt()); - position.set(Position.PREFIX_COUNT + 3, buf.readUnsignedInt()); + position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + 2, buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + 3, buf.readUnsignedIntLE()); } positions.add(position); } - buf.readUnsignedInt(); // crc + buf.readUnsignedIntLE(); // crc if (type == MSG_LOG_RECORDS) { requestArchive(channel); diff --git a/src/org/traccar/protocol/AplicomFrameDecoder.java b/src/org/traccar/protocol/AplicomFrameDecoder.java index 24d55f1cf..6e81e8202 100644 --- a/src/org/traccar/protocol/AplicomFrameDecoder.java +++ b/src/org/traccar/protocol/AplicomFrameDecoder.java @@ -15,19 +15,19 @@ */
package org.traccar.protocol;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import org.traccar.BaseFrameDecoder;
-public class AplicomFrameDecoder extends FrameDecoder {
+public class AplicomFrameDecoder extends BaseFrameDecoder {
@Override
protected Object decode(
- ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
+ ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
// Skip Alive message
- while (buf.readable() && Character.isDigit(buf.getByte(buf.readerIndex()))) {
+ while (buf.isReadable() && Character.isDigit(buf.getByte(buf.readerIndex()))) {
buf.readByte();
}
@@ -53,7 +53,7 @@ public class AplicomFrameDecoder extends FrameDecoder { // Return buffer
if (buf.readableBytes() >= length) {
- return buf.readBytes(length);
+ return buf.readRetainedSlice(length);
}
return null;
diff --git a/src/org/traccar/protocol/AplicomProtocol.java b/src/org/traccar/protocol/AplicomProtocol.java index 80f6f528f..6b9074163 100644 --- a/src/org/traccar/protocol/AplicomProtocol.java +++ b/src/org/traccar/protocol/AplicomProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class AplicomProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new AplicomFrameDecoder()); pipeline.addLast("objectDecoder", new AplicomProtocolDecoder(AplicomProtocol.this)); } diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 7ed187937..54b15700a 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; @@ -82,7 +82,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { private static final int EVENT_DATA = 119; - private void decodeEventData(Position position, ChannelBuffer buf, int event) { + private void decodeEventData(Position position, ByteBuf buf, int event) { switch (event) { case 2: case 40: @@ -117,7 +117,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeCanData(ChannelBuffer buf, Position position) { + private void decodeCanData(ByteBuf buf, Position position) { buf.readUnsignedMedium(); // packet identifier position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); @@ -128,63 +128,63 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(8); - ArrayList<ChannelBuffer> values = new ArrayList<>(count); + ArrayList<ByteBuf> values = new ArrayList<>(count); for (int i = 0; i < count; i++) { - values.add(buf.readBytes(8)); + values.add(buf.readSlice(8)); } for (int i = 0; i < count; i++) { - ChannelBuffer value = values.get(i); + ByteBuf value = values.get(i); switch (buf.readInt()) { case 0x20D: - position.set(Position.KEY_RPM, ChannelBuffers.swapShort(value.readShort())); - position.set("dieselTemperature", ChannelBuffers.swapShort(value.readShort()) * 0.1); - position.set("batteryVoltage", ChannelBuffers.swapShort(value.readShort()) * 0.01); - position.set("supplyAirTempDep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); + position.set(Position.KEY_RPM, value.readShortLE()); + position.set("dieselTemperature", value.readShortLE() * 0.1); + position.set("batteryVoltage", value.readShortLE() * 0.01); + position.set("supplyAirTempDep1", value.readShortLE() * 0.1); break; case 0x30D: - position.set("activeAlarm", ChannelBuffers.hexDump(value)); + position.set("activeAlarm", ByteBufUtil.hexDump(value)); break; case 0x40C: - position.set("airTempDep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); - position.set("airTempDep2", ChannelBuffers.swapShort(value.readShort()) * 0.1); + position.set("airTempDep1", value.readShortLE() * 0.1); + position.set("airTempDep2", value.readShortLE() * 0.1); break; case 0x40D: - position.set("coldUnitState", ChannelBuffers.hexDump(value)); + position.set("coldUnitState", ByteBufUtil.hexDump(value)); break; case 0x50C: - position.set("defrostTempDep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); - position.set("defrostTempDep2", ChannelBuffers.swapShort(value.readShort()) * 0.1); + position.set("defrostTempDep1", value.readShortLE() * 0.1); + position.set("defrostTempDep2", value.readShortLE() * 0.1); break; case 0x50D: - position.set("condenserPressure", ChannelBuffers.swapShort(value.readShort()) * 0.1); - position.set("suctionPressure", ChannelBuffers.swapShort(value.readShort()) * 0.1); + position.set("condenserPressure", value.readShortLE() * 0.1); + position.set("suctionPressure", value.readShortLE() * 0.1); break; case 0x58C: value.readByte(); value.readShort(); // index switch (value.readByte()) { case 0x01: - position.set("setpointZone1", ChannelBuffers.swapInt(value.readInt()) * 0.1); + position.set("setpointZone1", value.readIntLE() * 0.1); break; case 0x02: - position.set("setpointZone2", ChannelBuffers.swapInt(value.readInt()) * 0.1); + position.set("setpointZone2", value.readIntLE() * 0.1); break; case 0x05: - position.set("unitType", ChannelBuffers.swapInt(value.readInt())); + position.set("unitType", value.readIntLE()); break; case 0x13: - position.set("dieselHours", ChannelBuffers.swapInt(value.readInt()) / 60 / 60); + position.set("dieselHours", value.readIntLE() / 60 / 60); break; case 0x14: - position.set("electricHours", ChannelBuffers.swapInt(value.readInt()) / 60 / 60); + position.set("electricHours", value.readIntLE() / 60 / 60); break; case 0x17: - position.set("serviceIndicator", ChannelBuffers.swapInt(value.readInt())); + position.set("serviceIndicator", value.readIntLE()); break; case 0x18: - position.set("softwareVersion", ChannelBuffers.swapInt(value.readInt()) * 0.01); + position.set("softwareVersion", value.readIntLE() * 0.01); break; default: break; @@ -197,7 +197,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeD(Position position, ChannelBuffer buf, int selector, int event) { + private void decodeD(Position position, ByteBuf buf, int selector, int event) { if ((selector & 0x0008) != 0) { position.setValid((buf.readUnsignedByte() & 0x40) != 0); @@ -292,12 +292,12 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if (Context.getConfig().getBoolean(getProtocolName() + ".can") - && buf.readable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { + && buf.isReadable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { decodeCanData(buf, position); } } - private void decodeE(Position position, ChannelBuffer buf, int selector) { + private void decodeE(Position position, ByteBuf buf, int selector) { if ((selector & 0x0008) != 0) { position.set("tachographEvent", buf.readUnsignedShort()); @@ -349,13 +349,13 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0800) != 0) { - position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim()); + position.set(Position.KEY_VIN, buf.readSlice(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(); + String card = buf.readSlice(20).toString(StandardCharsets.US_ASCII).trim(); if (!card.isEmpty()) { position.set("card1", card); } @@ -364,7 +364,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { 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(); + String card = buf.readSlice(20).toString(StandardCharsets.US_ASCII).trim(); if (!card.isEmpty()) { position.set("card2", card); } @@ -373,13 +373,13 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { if ((selector & 0x10000) != 0) { int count = buf.readUnsignedByte(); for (int i = 1; i <= count; i++) { - position.set("driver" + i, buf.readBytes(22).toString(StandardCharsets.US_ASCII).trim()); + position.set("driver" + i, buf.readSlice(22).toString(StandardCharsets.US_ASCII).trim()); position.set("driverTime" + i, buf.readUnsignedInt()); } } } - private void decodeH(Position position, ChannelBuffer buf, int selector) { + private void decodeH(Position position, ByteBuf buf, int selector) { if ((selector & 0x0004) != 0) { getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); @@ -457,7 +457,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeEB(Position position, ChannelBuffer buf) { + private void decodeEB(Position position, ByteBuf buf) { if (buf.readByte() != (byte) 'E' || buf.readByte() != (byte) 'B') { return; @@ -477,7 +477,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { switch (type) { case 0x01: - position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length))); + position.set("brakeFlags", ByteBufUtil.hexDump(buf.readSlice(length))); break; case 0x02: position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); @@ -507,10 +507,10 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set("vdcActiveCounter", buf.readUnsignedShort()); break; case 0x0B: - position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length))); + position.set("brakeMinMaxData", ByteBufUtil.hexDump(buf.readSlice(length))); break; case 0x0C: - position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length))); + position.set("missingPgn", ByteBufUtil.hexDump(buf.readSlice(length))); break; case 0x0D: buf.readUnsignedByte(); @@ -526,7 +526,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeF(Position position, ChannelBuffer buf, int selector) { + private void decodeF(Position position, ByteBuf buf, int selector) { getLastLocation(position, null); @@ -549,7 +549,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0020) != 0) { - position.set(Position.KEY_HOURS, buf.readUnsignedInt()); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(buf.readUnsignedInt())); position.set("serviceDistance", buf.readInt()); position.set("driverActivity", buf.readUnsignedByte()); position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); @@ -557,7 +557,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0040) != 0) { - position.set("totalFuelUsed", buf.readUnsignedInt()); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt()); } if ((selector & 0x0080) != 0) { @@ -579,12 +579,64 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set("overspeedCount", buf.readUnsignedByte()); } + if ((selector & 0x0800) != 0) { + position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 0.05); + position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); + } + + if ((selector & 0x1000) != 0) { + position.set("ambientTemperature", buf.readUnsignedShort() * 0.03125 - 273); + buf.readUnsignedShort(); // fuel rate + position.set("fuelEconomy", buf.readUnsignedShort() / 512.0); + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt() * 0.001); + buf.readUnsignedByte(); // pto drive engagement + } + + if ((selector & 0x2000) != 0) { + buf.skipBytes(buf.readUnsignedByte()); // driver identification + } + + if ((selector & 0x4000) != 0) { + position.set("torque", buf.readUnsignedByte()); + position.set("brakePressure1", buf.readUnsignedByte() * 8); + position.set("brakePressure2", buf.readUnsignedByte() * 8); + position.set("grossWeight", buf.readUnsignedShort() * 10); + position.set("exhaustFluid", buf.readUnsignedByte() * 0.4); + buf.readUnsignedByte(); // retarder torque mode + position.set("retarderTorque", buf.readUnsignedByte()); + position.set("retarderSelection", buf.readUnsignedByte() * 0.4); + buf.skipBytes(8); // tell tale status block 1 + buf.skipBytes(8); // tell tale status block 2 + buf.skipBytes(8); // tell tale status block 3 + buf.skipBytes(8); // tell tale status block 4 + } + + if ((selector & 0x8000) != 0) { + position.set("parkingBrakeStatus", buf.readUnsignedByte()); + position.set("doorStatus", buf.readUnsignedByte()); + buf.skipBytes(8); // status per door + position.set("alternatorStatus", buf.readUnsignedByte()); + position.set("selectedGear", buf.readUnsignedByte()); + position.set("currentGear", buf.readUnsignedByte()); + buf.skipBytes(4 * 2); // air suspension pressure + } + + if ((selector & 0x0400) != 0) { + int count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + position.set("axle" + i, buf.readUnsignedShort()); + } + } + } @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; char protocol = (char) buf.readByte(); int version = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/AppelloProtocol.java b/src/org/traccar/protocol/AppelloProtocol.java index 8581850a1..33c7bbeed 100644 --- a/src/org/traccar/protocol/AppelloProtocol.java +++ b/src/org/traccar/protocol/AppelloProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class AppelloProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/AppelloProtocolDecoder.java b/src/org/traccar/protocol/AppelloProtocolDecoder.java index bf95b4068..ea0a2e243 100644 --- a/src/org/traccar/protocol/AppelloProtocolDecoder.java +++ b/src/org/traccar/protocol/AppelloProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/AquilaProtocol.java b/src/org/traccar/protocol/AquilaProtocol.java index c1de71cd3..b8c8e45d9 100644 --- a/src/org/traccar/protocol/AquilaProtocol.java +++ b/src/org/traccar/protocol/AquilaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class AquilaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java index d8081612d..8e4343ac4 100644 --- a/src/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/org/traccar/protocol/AquilaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -32,7 +36,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN = new PatternBuilder() + private static final Pattern PATTERN_A = new PatternBuilder() .text("$$") .expression("[^,]*,") // client .number("(d+),") // device serial number @@ -129,11 +133,9 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("xx") // checksum .compile(); - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Position decodeA(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN, (String) msg); + Parser parser = new Parser(PATTERN_A, sentence); if (!parser.matches()) { return null; } @@ -215,4 +217,130 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_B = new PatternBuilder() + .text("$Header,") + .expression("[^,]+,") // client + .expression("[^,]+,") // firmware version + .expression(".{2},") // type + .number("d+,") // message id + .expression("[LH],") // status + .number("(d+),") // imei + .expression("[^,]+,") // registration number + .number("([01]),") // validity + .number("(dd)(dd)(dddd),") // date (ddmmyyyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(-?d+.d+),") // latitude + .expression("([NS]),") + .number("(-?d+.d+),") // longitude + .expression("([EW]),") + .number("(d+.d+),") // speed + .number("(d+),") // course + .number("(d+),") // satellites + .number("(-?d+.d+),") // altitude + .number("(d+.d+),") // pdop + .number("(d+.d+),") // hdop + .expression("[^,]+,") // operator + .number("([01]),") // ignition + .number("([01]),") // charge + .number("(d+.d+),") // power + .number("(d+.d+),") // battery + .number("([01]),") // emergency + .expression("[CO],") // tamper + .number("(d+),") // rssi + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+),") // cid + .number("(d+),(x+),(x+),") // cell 1 + .number("(d+),(x+),(x+),") // cell 2 + .number("(d+),(x+),(x+),") // cell 3 + .number("(d+),(x+),(x+),") // cell 4 + .number("([01])+,") // inputs + .number("([01])+,") // outputs + .number("d+,") // frame number + .number("(d+.d+),") // adc1 + .number("(d+.d+),") // adc2 + .number("d+,") // delta distance + .any() + .compile(); + + private Position decodeB(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_B, sentence); + if (!parser.matches()) { + return null; + } + + String id = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(parser.nextInt() == 1); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + position.setAltitude(parser.nextDouble()); + + position.set(Position.KEY_PDOP, parser.nextDouble()); + position.set(Position.KEY_HDOP, parser.nextDouble()); + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + position.set(Position.KEY_CHARGE, parser.nextInt() == 1); + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + if (parser.nextInt() == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + if (channel != null) { + String password = Context.getIdentityManager().lookupAttributeString( + position.getDeviceId(), getProtocolName() + ".password", "aquila123", true); + channel.writeAndFlush(new NetworkMessage( + "#set$" + id + "@" + password + "#EMR_MODE:0*", remoteAddress)); + } + } + + Network network = new Network(); + + int rssi = parser.nextInt(); + int mcc = parser.nextInt(); + int mnc = parser.nextInt(); + + network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi)); + for (int i = 0; i < 4; i++) { + rssi = parser.nextInt(); + network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi)); + } + + position.setNetwork(network); + + position.set(Position.KEY_INPUT, parser.nextBinInt()); + position.set(Position.KEY_OUTPUT, parser.nextBinInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + if (sentence.startsWith("$$")) { + return decodeA(channel, remoteAddress, sentence); + } else { + return decodeB(channel, remoteAddress, sentence); + } + } + } diff --git a/src/org/traccar/protocol/Ardi01Protocol.java b/src/org/traccar/protocol/Ardi01Protocol.java index 446592bd0..5242df08c 100644 --- a/src/org/traccar/protocol/Ardi01Protocol.java +++ b/src/org/traccar/protocol/Ardi01Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Ardi01Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/org/traccar/protocol/Ardi01ProtocolDecoder.java index dea9e3483..7e25159b1 100644 --- a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java +++ b/src/org/traccar/protocol/Ardi01ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/ArknavProtocol.java b/src/org/traccar/protocol/ArknavProtocol.java index c22e5f443..3497ab8bb 100644 --- a/src/org/traccar/protocol/ArknavProtocol.java +++ b/src/org/traccar/protocol/ArknavProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class ArknavProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/ArknavProtocolDecoder.java b/src/org/traccar/protocol/ArknavProtocolDecoder.java index aeea4a734..c1a297e97 100644 --- a/src/org/traccar/protocol/ArknavProtocolDecoder.java +++ b/src/org/traccar/protocol/ArknavProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/ArknavX8Protocol.java b/src/org/traccar/protocol/ArknavX8Protocol.java index e759b5294..f5ad81660 100644 --- a/src/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/org/traccar/protocol/ArknavX8Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class ArknavX8Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java index 47cc267fe..60d7fe0db 100644 --- a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ b/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/ArnaviProtocol.java b/src/org/traccar/protocol/ArnaviProtocol.java index 956f2329a..88203fdbe 100644 --- a/src/org/traccar/protocol/ArnaviProtocol.java +++ b/src/org/traccar/protocol/ArnaviProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class ArnaviProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/org/traccar/protocol/ArnaviProtocolDecoder.java index ec96343fe..7649dddf6 100644 --- a/src/org/traccar/protocol/ArnaviProtocolDecoder.java +++ b/src/org/traccar/protocol/ArnaviProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/AstraProtocol.java b/src/org/traccar/protocol/AstraProtocol.java index 87c562a9d..301afa532 100644 --- a/src/org/traccar/protocol/AstraProtocol.java +++ b/src/org/traccar/protocol/AstraProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,16 +30,16 @@ public class AstraProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast("objectDecoder", new AstraProtocolDecoder(AstraProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new AstraProtocolDecoder(AstraProtocol.this)); } }); diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java index 79c7eba3f..c386c7757 100644 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Log; @@ -44,10 +45,10 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (channel != null) { - channel.write(ChannelBuffers.wrappedBuffer(new byte[] {0x06}), remoteAddress); + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(new byte[] {0x06}), remoteAddress)); } buf.readUnsignedByte(); // protocol @@ -104,9 +105,9 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // geofence events if (BitUtil.check(status, 8)) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readSlice(7).toString(StandardCharsets.US_ASCII)); position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); - position.set(Position.KEY_HOURS, buf.readUnsignedShort()); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(buf.readUnsignedShort())); } if (BitUtil.check(status, 6)) { diff --git a/src/org/traccar/protocol/At2000FrameDecoder.java b/src/org/traccar/protocol/At2000FrameDecoder.java index af257d0fb..5fa82a5f7 100644 --- a/src/org/traccar/protocol/At2000FrameDecoder.java +++ b/src/org/traccar/protocol/At2000FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,38 +15,37 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.NetworkMessage; -import java.nio.ByteOrder; - -public class At2000FrameDecoder extends FrameDecoder { +public class At2000FrameDecoder extends BaseFrameDecoder { private static final int BLOCK_LENGTH = 16; private static final int ACK_LENGTH = 496; private boolean firstPacket = true; - private ChannelBuffer currentBuffer; + private ByteBuf currentBuffer; private int acknowledgedBytes; private void sendResponse(Channel channel) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 2 * BLOCK_LENGTH); + ByteBuf response = Unpooled.buffer(2 * BLOCK_LENGTH); response.writeByte(At2000ProtocolDecoder.MSG_ACKNOWLEDGEMENT); - response.writeMedium(ChannelBuffers.swapMedium(1)); + response.writeMedium(1); response.writeByte(0x00); // success response.writerIndex(2 * BLOCK_LENGTH); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 5) { return null; @@ -55,9 +54,9 @@ public class At2000FrameDecoder extends FrameDecoder { int length; if (firstPacket) { firstPacket = false; - length = buf.getUnsignedMedium(buf.readerIndex() + 2); + length = buf.getUnsignedMediumLE(buf.readerIndex() + 2); } else { - length = buf.getUnsignedMedium(buf.readerIndex() + 1); + length = buf.getUnsignedMediumLE(buf.readerIndex() + 1); } length += BLOCK_LENGTH; @@ -73,7 +72,7 @@ public class At2000FrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/At2000Protocol.java b/src/org/traccar/protocol/At2000Protocol.java index 35aa0b469..1aca8bb13 100644 --- a/src/org/traccar/protocol/At2000Protocol.java +++ b/src/org/traccar/protocol/At2000Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class At2000Protocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class At2000Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new At2000FrameDecoder()); pipeline.addLast("objectDecoder", new At2000ProtocolDecoder(At2000Protocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java index e0f2b4278..4457854e3 100644 --- a/src/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/org/traccar/protocol/At2000ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -28,7 +29,6 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; @@ -52,11 +52,11 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder { private static void sendRequest(Channel channel) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, BLOCK_LENGTH); + ByteBuf response = Unpooled.buffer(BLOCK_LENGTH); response.writeByte(MSG_TRACK_REQUEST); - response.writeMedium(ChannelBuffers.swapMedium(0)); + response.writeMedium(0); response.writerIndex(BLOCK_LENGTH); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -64,19 +64,19 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getUnsignedByte(buf.readerIndex()) == 0x01) { buf.readUnsignedByte(); // codec id } int type = buf.readUnsignedByte(); - buf.readUnsignedMedium(); // length + buf.readUnsignedMediumLE(); // length buf.skipBytes(BLOCK_LENGTH - 1 - 3); if (type == MSG_DEVICE_ID) { - String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); if (getDeviceSession(channel, remoteAddress, imei) != null) { byte[] iv = new byte[BLOCK_LENGTH]; @@ -106,51 +106,54 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder { return null; // empty message } - byte[] data = new byte[buf.capacity() - BLOCK_LENGTH]; - buf.readBytes(data); - buf = ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, cipher.update(data)); - List<Position> positions = new LinkedList<>(); - while (buf.readableBytes() >= 63) { + byte[] data = new byte[buf.capacity() - BLOCK_LENGTH]; + buf.readBytes(data); + buf = Unpooled.wrappedBuffer(cipher.update(data)); + try { + while (buf.readableBytes() >= 63) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedShort(); // index - buf.readUnsignedShort(); // reserved + buf.readUnsignedShortLE(); // index + buf.readUnsignedShortLE(); // reserved - position.setValid(true); + position.setValid(true); - position.setTime(new Date(buf.readLong() * 1000)); + position.setTime(new Date(buf.readLongLE() * 1000)); - position.setLatitude(buf.readFloat()); - position.setLongitude(buf.readFloat()); - position.setAltitude(buf.readFloat()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloat())); - position.setCourse(buf.readFloat()); + position.setLatitude(buf.readFloatLE()); + position.setLongitude(buf.readFloatLE()); + position.setAltitude(buf.readFloatLE()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); + position.setCourse(buf.readFloatLE()); - buf.readUnsignedInt(); // geozone event - buf.readUnsignedInt(); // io events - buf.readUnsignedInt(); // geozone value - buf.readUnsignedInt(); // io values - buf.readUnsignedShort(); // operator + buf.readUnsignedIntLE(); // geozone event + buf.readUnsignedIntLE(); // io events + buf.readUnsignedIntLE(); // geozone value + buf.readUnsignedIntLE(); // io values + buf.readUnsignedShortLE(); // operator - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - buf.readUnsignedShort(); // cid - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - buf.readUnsignedByte(); // current profile + buf.readUnsignedShortLE(); // cid + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + buf.readUnsignedByte(); // current profile - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - positions.add(position); + positions.add(position); + } + } finally { + buf.release(); } return positions; diff --git a/src/org/traccar/protocol/AtrackFrameDecoder.java b/src/org/traccar/protocol/AtrackFrameDecoder.java index ce4a9a65f..3d33d9862 100644 --- a/src/org/traccar/protocol/AtrackFrameDecoder.java +++ b/src/org/traccar/protocol/AtrackFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,42 +15,42 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BufferUtil; -public class AtrackFrameDecoder extends FrameDecoder { +public class AtrackFrameDecoder extends BaseFrameDecoder { private static final int KEEPALIVE_LENGTH = 12; @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() >= 2) { if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { if (buf.readableBytes() >= KEEPALIVE_LENGTH) { - return buf.readBytes(KEEPALIVE_LENGTH); + return buf.readRetainedSlice(KEEPALIVE_LENGTH); } - } else if (buf.getUnsignedShort(buf.readerIndex()) == 0x4050) { + } else if (buf.getUnsignedShort(buf.readerIndex()) == 0x4050 && buf.getByte(buf.readerIndex() + 2) != ',') { if (buf.readableBytes() > 6) { int length = buf.getUnsignedShort(buf.readerIndex() + 4) + 4 + 2; if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } } else { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("\r\n")); + int endIndex = BufferUtil.indexOf("\r\n", buf); if (endIndex > 0) { - return buf.readBytes(endIndex - buf.readerIndex() + 2); + return buf.readRetainedSlice(endIndex - buf.readerIndex() + 2); } } diff --git a/src/org/traccar/protocol/AtrackProtocol.java b/src/org/traccar/protocol/AtrackProtocol.java index 5104e5587..74840a1f5 100644 --- a/src/org/traccar/protocol/AtrackProtocol.java +++ b/src/org/traccar/protocol/AtrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -34,17 +32,17 @@ public class AtrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new AtrackFrameDecoder()); pipeline.addLast("objectEncoder", new AtrackProtocolEncoder()); pipeline.addLast("objectDecoder", new AtrackProtocolDecoder(AtrackProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new AtrackProtocolEncoder()); pipeline.addLast("objectDecoder", new AtrackProtocolDecoder(AtrackProtocol.this)); } diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 8138f0fcb..ebccfec94 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -15,12 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -80,25 +81,25 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(12); + ByteBuf response = Unpooled.buffer(12); response.writeShort(0xfe02); response.writeLong(rawId); response.writeShort(index); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } - private static String readString(ChannelBuffer buf) { + private static String readString(ByteBuf buf) { String result = null; int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); if (index > buf.readerIndex()) { - result = buf.readBytes(index - buf.readerIndex()).toString(StandardCharsets.US_ASCII); + result = buf.readSlice(index - buf.readerIndex()).toString(StandardCharsets.US_ASCII); } buf.readByte(); return result; } - private void readCustomData(Position position, ChannelBuffer buf, String form) { + private void readCustomData(Position position, ByteBuf buf, String form) { CellTower cellTower = new CellTower(); String[] keys = form.substring(1).split("%"); for (String key : keys) { @@ -219,7 +220,8 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) { + private Position decodeInfo(Channel channel, SocketAddress remoteAddress, String sentence) { + Position position = new Position(getProtocolName()); getLastLocation(position, null); @@ -258,21 +260,70 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private static final Pattern PATTERN = new PatternBuilder() + .text("@P,") + .number("x+,") // checksum + .number("d+,") // length + .number("d+,") // index + .number("(d+),") // imei + .number("(dddd)(dd)(dd)") // date (yymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("d+,") // rtc date and time + .number("d+,") // device date and time + .number("(-?d+),") // longitude + .number("(-?d+),") // latitude + .number("(d+),") // course + .number("(d+),") // report id + .number("(d+.d+),") // odometer + .number("(d+),") // hdop + .number("(d+),") // inputs + .number("(d+),") // speed + .number("(d+),") // outputs + .number("(d+),") // adc + .number("[^,]*,") // driver + .number("(d+),") // temp1 + .number("(d+),") // temp2 + .any() + .compile(); - ChannelBuffer buf = (ChannelBuffer) msg; + private Position decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { - if (channel != null) { - channel.write(buf, remoteAddress); // keep-alive message - } + Parser parser = new Parser(PATTERN, sentence); + if (!parser.matches()) { return null; - } else if (buf.getByte(buf.readerIndex()) == '$') { - return decodeString(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLongitude(parser.nextInt() * 0.000001); + position.setLatitude(parser.nextInt() * 0.000001); + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 100); + position.set(Position.KEY_HDOP, parser.nextInt() * 0.1); + position.set(Position.KEY_INPUT, parser.nextInt()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_OUTPUT, parser.nextInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 2, parser.nextInt()); + + return position; + } + + private List<Position> decodeBinary(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + buf.skipBytes(2); // prefix buf.readUnsignedShort(); // checksum buf.readUnsignedShort(); // length @@ -360,4 +411,24 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { return positions; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(buf, remoteAddress)); // keep-alive message + } + return null; + } else if (buf.getByte(buf.readerIndex()) == '$') { + return decodeInfo(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); + } else if (buf.getByte(buf.readerIndex() + 2) == ',') { + return decodeText(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); + } else { + return decodeBinary(channel, remoteAddress, buf); + } + } + } diff --git a/src/org/traccar/protocol/AtrackProtocolEncoder.java b/src/org/traccar/protocol/AtrackProtocolEncoder.java index 77f16527f..1aa580435 100644 --- a/src/org/traccar/protocol/AtrackProtocolEncoder.java +++ b/src/org/traccar/protocol/AtrackProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -29,7 +29,7 @@ public class AtrackProtocolEncoder extends BaseProtocolEncoder { switch (command.getType()) { case Command.TYPE_CUSTOM: - return ChannelBuffers.copiedBuffer( + return Unpooled.copiedBuffer( command.getString(Command.KEY_DATA) + "\r\n", StandardCharsets.US_ASCII); default: Log.warning(new UnsupportedOperationException(command.getType())); diff --git a/src/org/traccar/protocol/AuroProtocol.java b/src/org/traccar/protocol/AuroProtocol.java index e1b23478f..99affeba1 100644 --- a/src/org/traccar/protocol/AuroProtocol.java +++ b/src/org/traccar/protocol/AuroProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class AuroProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/AuroProtocolDecoder.java b/src/org/traccar/protocol/AuroProtocolDecoder.java index 3cb3a440c..e84b65bf3 100644 --- a/src/org/traccar/protocol/AuroProtocolDecoder.java +++ b/src/org/traccar/protocol/AuroProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/GlobeKeeperProtocol.java b/src/org/traccar/protocol/AustinNbProtocol.java index 9231c067c..1ffb6e4ad 100644 --- a/src/org/traccar/protocol/GlobeKeeperProtocol.java +++ b/src/org/traccar/protocol/AustinNbProtocol.java @@ -15,29 +15,28 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; -public class GlobeKeeperProtocol extends BaseProtocol { +public class AustinNbProtocol extends BaseProtocol { - public GlobeKeeperProtocol() { - super("globekeeper"); + public AustinNbProtocol() { + super("austinnb"); } @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); - pipeline.addLast("objectDecoder", new GlobeKeeperProtocolDecoder(GlobeKeeperProtocol.this)); + pipeline.addLast("objectDecoder", new AustinNbProtocolDecoder(AustinNbProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java b/src/org/traccar/protocol/AustinNbProtocolDecoder.java index c4daf4409..5e2ee6178 100644 --- a/src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java +++ b/src/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; @@ -23,11 +23,12 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.TimeZone; import java.util.regex.Pattern; -public class GlobeKeeperProtocolDecoder extends BaseProtocolDecoder { +public class AustinNbProtocolDecoder extends BaseProtocolDecoder { - public GlobeKeeperProtocolDecoder(GlobeKeeperProtocol protocol) { + public AustinNbProtocolDecoder(AustinNbProtocol protocol) { super(protocol); } @@ -37,6 +38,11 @@ public class GlobeKeeperProtocolDecoder extends BaseProtocolDecoder { .number("(dd):(dd):(dd);") // time .number("(-?d+,d+);") // latitude .number("(-?d+,d+);") // longitude + .number("(d+);") // azimuth + .number("(d+);") // angle + .number("(d+);") // range + .number("(d+);") // out of range + .expression("(.*)") // operator .any() .compile(); @@ -57,11 +63,16 @@ public class GlobeKeeperProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime()); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS, TimeZone.getDefault().getID())); position.setValid(true); - position.setLongitude(Double.parseDouble(parser.next().replace(',', '.'))); position.setLatitude(Double.parseDouble(parser.next().replace(',', '.'))); + position.setLongitude(Double.parseDouble(parser.next().replace(',', '.'))); + position.setCourse(parser.nextInt()); + position.set("angle", parser.nextInt()); + position.set("range", parser.nextInt()); + position.set("outOfRange", parser.nextInt()); + position.set("carrier", parser.next()); return position; } diff --git a/src/org/traccar/protocol/AutoFonFrameDecoder.java b/src/org/traccar/protocol/AutoFonFrameDecoder.java index 2fa1b4072..69f28133f 100644 --- a/src/org/traccar/protocol/AutoFonFrameDecoder.java +++ b/src/org/traccar/protocol/AutoFonFrameDecoder.java @@ -16,18 +16,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class AutoFonFrameDecoder extends FrameDecoder { +public class AutoFonFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { // Check minimum length if (buf.readableBytes() < 12) { @@ -58,7 +56,7 @@ public class AutoFonFrameDecoder extends FrameDecoder { // Check length and return buffer if (length != 0 && buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/AutoFonProtocol.java b/src/org/traccar/protocol/AutoFonProtocol.java index 927bda120..993f8610c 100644 --- a/src/org/traccar/protocol/AutoFonProtocol.java +++ b/src/org/traccar/protocol/AutoFonProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class AutoFonProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new AutoFonFrameDecoder()); pipeline.addLast("objectDecoder", new AutoFonProtocolDecoder(AutoFonProtocol.this)); } diff --git a/src/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/org/traccar/protocol/AutoFonProtocolDecoder.java index e243b93ea..c5a3692f2 100644 --- a/src/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -16,11 +16,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.model.CellTower; @@ -60,7 +62,7 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodePosition(DeviceSession deviceSession, ChannelBuffer buf, boolean history) { + private Position decodePosition(DeviceSession deviceSession, ByteBuf buf, boolean history) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -118,7 +120,7 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; int type = buf.readUnsignedByte(); @@ -129,14 +131,14 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // software version } - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null && channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeBytes("resp_crc=".getBytes(StandardCharsets.US_ASCII)); response.writeByte(buf.getByte(buf.writerIndex() - 1)); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return null; diff --git a/src/org/traccar/protocol/AutoGradeProtocol.java b/src/org/traccar/protocol/AutoGradeProtocol.java index 41bb8d9ad..ba51c2bfc 100644 --- a/src/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/org/traccar/protocol/AutoGradeProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class AutoGradeProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java index b98c68cbd..9b9ef7d46 100644 --- a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java +++ b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/AutoTrackProtocol.java b/src/org/traccar/protocol/AutoTrackProtocol.java new file mode 100644 index 000000000..d6d4ac177 --- /dev/null +++ b/src/org/traccar/protocol/AutoTrackProtocol.java @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.nio.ByteOrder; +import java.util.List; + +public class AutoTrackProtocol extends BaseProtocol { + + public AutoTrackProtocol() { + super("autotrack"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); + pipeline.addLast("objectDecoder", new AutoTrackProtocolDecoder(AutoTrackProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/org/traccar/protocol/AutoTrackProtocolDecoder.java new file mode 100644 index 000000000..370c561d9 --- /dev/null +++ b/src/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -0,0 +1,121 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; + +public class AutoTrackProtocolDecoder extends BaseProtocolDecoder { + + public AutoTrackProtocolDecoder(AutoTrackProtocol protocol) { + super(protocol); + } + + public static final int MSG_LOGIN_REQUEST = 51; + public static final int MSG_LOGIN_CONFIRM = 101; + public static final int MSG_TELEMETRY_1 = 52; + public static final int MSG_TELEMETRY_2 = 66; + public static final int MSG_TELEMETRY_3 = 67; + public static final int MSG_KEEP_ALIVE = 114; + + private Position decodeTelemetry(DeviceSession deviceSession, ByteBuf buf) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(new Date(1007078400000L + buf.readUnsignedIntLE() * 1000)); // seconds since 2002 + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE()); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + + position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); + buf.readUnsignedIntLE(); // di 3 count + buf.readUnsignedIntLE(); // di 4 count + + for (int i = 0; i < 5; i++) { + position.set(Position.PREFIX_ADC + (i + 1), buf.readUnsignedShortLE()); + } + + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); + position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readLongLE()); + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); + + buf.readUnsignedShortLE(); // checksum + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(4); // sync + int type = buf.readUnsignedByte(); + buf.readUnsignedShortLE(); // length + + switch (type) { + case MSG_LOGIN_REQUEST: + String imei = ByteBufUtil.hexDump(buf.readBytes(8)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { + return null; + } + int fuelConst = buf.readUnsignedShortLE(); + int tripConst = buf.readUnsignedShortLE(); + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeInt(0xF1F1F1F1); // sync + response.writeByte(MSG_LOGIN_CONFIRM); + response.writeShortLE(12); // length + response.writeBytes(ByteBufUtil.decodeHexDump(imei)); + response.writeShortLE(fuelConst); + response.writeShortLE(tripConst); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + return null; + case MSG_TELEMETRY_1: + case MSG_TELEMETRY_2: + case MSG_TELEMETRY_3: + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + return decodeTelemetry(deviceSession, buf); + default: + return null; + } + } + +} diff --git a/src/org/traccar/protocol/AvemaProtocol.java b/src/org/traccar/protocol/AvemaProtocol.java new file mode 100644 index 000000000..e3fd61baa --- /dev/null +++ b/src/org/traccar/protocol/AvemaProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class AvemaProtocol extends BaseProtocol { + + public AvemaProtocol() { + super("avema"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new AvemaProtocolDecoder(AvemaProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/AvemaProtocolDecoder.java b/src/org/traccar/protocol/AvemaProtocolDecoder.java new file mode 100644 index 000000000..483c7e2c8 --- /dev/null +++ b/src/org/traccar/protocol/AvemaProtocolDecoder.java @@ -0,0 +1,106 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class AvemaProtocolDecoder extends BaseProtocolDecoder { + + public AvemaProtocolDecoder(AvemaProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .number("(d+),") // device id + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(-?d+.d+),") // longitude + .number("(-?d+.d+),") // latitude + .number("(d+),") // speed + .number("(d+),") // course + .number("(-?d+),") // altitude + .number("(d+),") // satellites + .number("(d+),") // event + .number("(d+.d+),") // odometer + .number("(d+),") // input + .number("(d+.d+)V,") // adc 1 + .number("(d+.d+)V,") // adc 2 + .number("(d+),") // output + .number("(d),") // roaming + .number("(d+),") // rssi + .number("d,") // communication system + .number("(ddd)") // mcc + .number("(dd),") // mnc + .number("(x+),") // lac + .number("(x+),") // cid + .number("([^,]+)?") // rfid + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + position.set(Position.KEY_INPUT, parser.nextInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); + position.set(Position.KEY_OUTPUT, parser.nextInt()); + position.set(Position.KEY_ROAMING, parser.nextInt() == 1); + + int rssi = parser.nextInt(); + position.setNetwork(new Network(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi))); + + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/Avl301Protocol.java b/src/org/traccar/protocol/Avl301Protocol.java index 4a217bad6..98a9b8edc 100644 --- a/src/org/traccar/protocol/Avl301Protocol.java +++ b/src/org/traccar/protocol/Avl301Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class Avl301Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); pipeline.addLast("objectDecoder", new Avl301ProtocolDecoder(Avl301Protocol.this)); } diff --git a/src/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/org/traccar/protocol/Avl301ProtocolDecoder.java index 056395d35..a3697117b 100644 --- a/src/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -33,7 +34,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private String readImei(ChannelBuffer buf) { + private String readImei(ByteBuf buf) { int b = buf.readUnsignedByte(); StringBuilder imei = new StringBuilder(); imei.append(b & 0x0F); @@ -51,12 +52,12 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, int type) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(5); + ByteBuf response = Unpooled.buffer(5); response.writeByte('$'); response.writeByte(type); response.writeByte('#'); response.writeByte('\r'); response.writeByte('\n'); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -64,7 +65,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(1); // header int type = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/BceFrameDecoder.java b/src/org/traccar/protocol/BceFrameDecoder.java index 4fac79f85..381a97696 100644 --- a/src/org/traccar/protocol/BceFrameDecoder.java +++ b/src/org/traccar/protocol/BceFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class BceFrameDecoder extends FrameDecoder { +public class BceFrameDecoder extends BaseFrameDecoder { private static final int HANDSHAKE_LENGTH = 7; // "#BCE#\r\n" private boolean header = true; - private static byte checksum(ChannelBuffer buf, int end) { + private static byte checksum(ByteBuf buf, int end) { byte result = 0; for (int i = 0; i < end; i++) { result += buf.getByte(buf.readerIndex() + i); @@ -36,9 +36,7 @@ public class BceFrameDecoder extends FrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (header && buf.readableBytes() >= HANDSHAKE_LENGTH) { buf.skipBytes(HANDSHAKE_LENGTH); @@ -48,10 +46,10 @@ public class BceFrameDecoder extends FrameDecoder { int end = 8; // IMEI while (buf.readableBytes() >= end + 2 + 1 + 1 + 1) { - end += buf.getUnsignedShort(buf.readerIndex() + end) + 2; + end += buf.getUnsignedShortLE(buf.readerIndex() + end) + 2; if (buf.readableBytes() > end && checksum(buf, end) == buf.getByte(buf.readerIndex() + end)) { - return buf.readBytes(end + 1); + return buf.readRetainedSlice(end + 1); } } diff --git a/src/org/traccar/protocol/BceProtocol.java b/src/org/traccar/protocol/BceProtocol.java index 5374fd0e1..880a4df70 100644 --- a/src/org/traccar/protocol/BceProtocol.java +++ b/src/org/traccar/protocol/BceProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class BceProtocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class BceProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new BceFrameDecoder()); pipeline.addLast("objectDecoder", new BceProtocolDecoder(BceProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/BceProtocolDecoder.java b/src/org/traccar/protocol/BceProtocolDecoder.java index 22d6a5aa8..301be7847 100644 --- a/src/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/org/traccar/protocol/BceProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,18 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -49,9 +50,9 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - String imei = String.format("%015d", buf.readLong()); + String imei = String.format("%015d", buf.readLongLE()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; @@ -61,7 +62,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 1) { - int dataEnd = buf.readUnsignedShort() + buf.readerIndex(); + int dataEnd = buf.readUnsignedShortLE() + buf.readerIndex(); int type = buf.readUnsignedByte(); int confirmKey = buf.readUnsignedByte() & 0x7F; @@ -72,7 +73,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { int structEnd = buf.readUnsignedByte() + buf.readerIndex(); - long time = buf.readUnsignedInt(); + long time = buf.readUnsignedIntLE(); if ((time & 0x0f) == DATA_TYPE) { time = time >> 4 << 1; @@ -83,7 +84,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { int mask; List<Integer> masks = new LinkedList<>(); do { - mask = buf.readUnsignedShort(); + mask = buf.readUnsignedShortLE(); masks.add(mask); } while (BitUtil.check(mask, 15)); @@ -91,27 +92,27 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 0)) { position.setValid(true); - position.setLongitude(buf.readFloat()); - position.setLatitude(buf.readFloat()); - position.setSpeed(buf.readUnsignedByte()); + position.setLongitude(buf.readFloatLE()); + position.setLatitude(buf.readFloatLE()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - int gps = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, gps & 0xf); - position.set(Position.KEY_HDOP, gps >> 4); + int status = buf.readUnsignedByte(); + position.set(Position.KEY_SATELLITES, BitUtil.to(status, 4)); + position.set(Position.KEY_HDOP, BitUtil.from(status, 4)); - position.setCourse(buf.readUnsignedByte()); - position.setAltitude(buf.readUnsignedShort()); + position.setCourse(buf.readUnsignedByte() * 2); + position.setAltitude(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); } if (BitUtil.check(mask, 1)) { - position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); } for (int i = 1; i <= 8; i++) { if (BitUtil.check(mask, i + 1)) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE()); } } @@ -130,8 +131,8 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 14)) { position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedByte(), - buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShortLE(), buf.readUnsignedByte(), + buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), buf.readUnsignedByte()))); buf.readUnsignedByte(); } @@ -146,9 +147,9 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { // Send response if (type == MSG_ASYNC_STACK && channel != null) { - ChannelBuffer response = ChannelBuffers.buffer(ByteOrder.LITTLE_ENDIAN, 8 + 2 + 2 + 1); - response.writeLong(Long.parseLong(imei)); - response.writeShort(2); + ByteBuf response = Unpooled.buffer(8 + 2 + 2 + 1); + response.writeLongLE(Long.parseLong(imei)); + response.writeShortLE(2); response.writeByte(MSG_STACK_COFIRM); response.writeByte(confirmKey); @@ -158,7 +159,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { } response.writeByte(checksum); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } diff --git a/src/org/traccar/protocol/BlackKiteProtocol.java b/src/org/traccar/protocol/BlackKiteProtocol.java index db32f5328..423562907 100644 --- a/src/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/org/traccar/protocol/BlackKiteProtocol.java @@ -1,6 +1,6 @@ /* * Copyright 2015 Vijay Kumar (vijaykumar@zilogic.com) - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -16,12 +16,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class BlackKiteProtocol extends BaseProtocol { @@ -32,15 +30,13 @@ public class BlackKiteProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new GalileoFrameDecoder()); pipeline.addLast("objectDecoder", new BlackKiteProtocolDecoder(BlackKiteProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/org/traccar/protocol/BlackKiteProtocolDecoder.java index 7fc39fc7c..aebf970d0 100644 --- a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java +++ b/src/org/traccar/protocol/BlackKiteProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) * Copyright 2015 Vijay Kumar (vijaykumar@zilogic.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,16 +16,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashSet; @@ -56,11 +56,11 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { private static final int TAG_XT3 = 0x62; private void sendReply(Channel channel, int checksum) { - ChannelBuffer reply = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 3); - reply.writeByte(0x02); - reply.writeShort((short) checksum); if (channel != null) { - channel.write(reply); + ByteBuf reply = Unpooled.buffer(3); + reply.writeByte(0x02); + reply.writeShortLE((short) checksum); + channel.writeAndFlush(new NetworkMessage(reply, channel.remoteAddress())); } } @@ -68,10 +68,10 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header - int length = (buf.readUnsignedShort() & 0x7fff) + 3; + int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; List<Position> positions = new LinkedList<>(); Set<Integer> tags = new HashSet<>(); @@ -95,31 +95,31 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { switch (tag) { case TAG_IMEI: - getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); + getDeviceSession(channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); break; case TAG_DATE: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); break; case TAG_COORDINATES: hasLocation = true; position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00); - position.setLatitude(buf.readInt() / 1000000.0); - position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readIntLE() / 1000000.0); + position.setLongitude(buf.readIntLE() / 1000000.0); break; case TAG_SPEED_COURSE: - position.setSpeed(buf.readUnsignedShort() * 0.0539957); - position.setCourse(buf.readUnsignedShort() * 0.1); + position.setSpeed(buf.readUnsignedShortLE() * 0.0539957); + position.setCourse(buf.readUnsignedShortLE() * 0.1); break; case TAG_ALTITUDE: - position.setAltitude(buf.readShort()); + position.setAltitude(buf.readShortLE()); break; case TAG_STATUS: - int status = buf.readUnsignedShort(); + int status = buf.readUnsignedShortLE(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 9)); if (BitUtil.check(status, 15)) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); @@ -128,33 +128,33 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { break; case TAG_DIGITAL_INPUTS: - int input = buf.readUnsignedShort(); + int input = buf.readUnsignedShortLE(); for (int i = 0; i < 16; i++) { position.set(Position.PREFIX_IO + (i + 1), BitUtil.check(input, i)); } break; case TAG_DIGITAL_OUTPUTS: - int output = buf.readUnsignedShort(); + int output = buf.readUnsignedShortLE(); for (int i = 0; i < 16; i++) { position.set(Position.PREFIX_IO + (i + 17), BitUtil.check(output, i)); } break; case TAG_INPUT_VOLTAGE1: - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() / 1000.0); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() / 1000.0); break; case TAG_INPUT_VOLTAGE2: - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort() / 1000.0); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() / 1000.0); break; case TAG_INPUT_VOLTAGE3: - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort() / 1000.0); + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE() / 1000.0); break; case TAG_INPUT_VOLTAGE4: - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShort() / 1000.0); + position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE() / 1000.0); break; case TAG_XT1: @@ -178,7 +178,7 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { return null; } - sendReply(channel, buf.readUnsignedShort()); + sendReply(channel, buf.readUnsignedShortLE()); for (Position p : positions) { p.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/org/traccar/protocol/BoxProtocol.java b/src/org/traccar/protocol/BoxProtocol.java index 36e7790f0..6e76ee635 100644 --- a/src/org/traccar/protocol/BoxProtocol.java +++ b/src/org/traccar/protocol/BoxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class BoxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/BoxProtocolDecoder.java b/src/org/traccar/protocol/BoxProtocolDecoder.java index 63238bcef..231fd9b36 100644 --- a/src/org/traccar/protocol/BoxProtocolDecoder.java +++ b/src/org/traccar/protocol/BoxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -62,7 +63,7 @@ public class BoxProtocolDecoder extends BaseProtocolDecoder { } else if (sentence.startsWith("E,")) { if (channel != null) { - channel.write("A," + sentence.substring(2) + "\r"); + channel.writeAndFlush(new NetworkMessage("A," + sentence.substring(2) + "\r", remoteAddress)); } } else if (sentence.startsWith("L,")) { diff --git a/src/org/traccar/protocol/CalAmpProtocol.java b/src/org/traccar/protocol/CalAmpProtocol.java index a3577f10c..29cb2974f 100644 --- a/src/org/traccar/protocol/CalAmpProtocol.java +++ b/src/org/traccar/protocol/CalAmpProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class CalAmpProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new CalAmpProtocolDecoder(CalAmpProtocol.this)); } }); diff --git a/src/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/org/traccar/protocol/CalAmpProtocolDecoder.java index f717d3c5d..d495e7400 100644 --- a/src/org/traccar/protocol/CalAmpProtocolDecoder.java +++ b/src/org/traccar/protocol/CalAmpProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -52,7 +54,7 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, SocketAddress remoteAddress, int type, int index, int result) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(10); + ByteBuf response = Unpooled.buffer(10); response.writeByte(SERVICE_RESPONSE); response.writeByte(MSG_ACK); response.writeShort(index); @@ -60,11 +62,11 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder { response.writeByte(result); response.writeByte(0); response.writeMedium(0); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } - private Position decodePosition(DeviceSession deviceSession, int type, ChannelBuffer buf) { + private Position decodePosition(DeviceSession deviceSession, int type, ByteBuf buf) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -143,14 +145,14 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (BitUtil.check(buf.getByte(buf.readerIndex()), 7)) { int content = buf.readUnsignedByte(); if (BitUtil.check(content, 0)) { - String id = ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedByte())); + String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())); getDeviceSession(channel, remoteAddress, id); } diff --git a/src/org/traccar/protocol/CarTrackProtocol.java b/src/org/traccar/protocol/CarTrackProtocol.java index d235c92be..2ac6598a4 100644 --- a/src/org/traccar/protocol/CarTrackProtocol.java +++ b/src/org/traccar/protocol/CarTrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class CarTrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/org/traccar/protocol/CarTrackProtocolDecoder.java index 94215379d..87c4ae345 100644 --- a/src/org/traccar/protocol/CarTrackProtocolDecoder.java +++ b/src/org/traccar/protocol/CarTrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) * Copyright 2014 Rohit * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/CarcellProtocol.java b/src/org/traccar/protocol/CarcellProtocol.java index c9fedad65..40ecfbbe7 100644 --- a/src/org/traccar/protocol/CarcellProtocol.java +++ b/src/org/traccar/protocol/CarcellProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -17,12 +17,11 @@ package org.traccar.protocol; import java.util.List; -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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,9 +36,9 @@ public class CarcellProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java index 52b777b81..a4da7982e 100644 --- a/src/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/org/traccar/protocol/CarcellProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -18,7 +18,7 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.util.regex.Pattern; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/CarscopProtocol.java b/src/org/traccar/protocol/CarscopProtocol.java index 01a754027..c52b025bc 100644 --- a/src/org/traccar/protocol/CarscopProtocol.java +++ b/src/org/traccar/protocol/CarscopProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class CarscopProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '^')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/CarscopProtocolDecoder.java b/src/org/traccar/protocol/CarscopProtocolDecoder.java index 7f9dcc3b7..d8634b512 100644 --- a/src/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/org/traccar/protocol/CarscopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/CastelProtocol.java b/src/org/traccar/protocol/CastelProtocol.java index d5ba5cd55..fcf461fde 100644 --- a/src/org/traccar/protocol/CastelProtocol.java +++ b/src/org/traccar/protocol/CastelProtocol.java @@ -15,11 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,26 +35,22 @@ public class CastelProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast("objectEncoder", new CastelProtocolEncoder()); pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); - - server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { + }); + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new CastelProtocolEncoder()); pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 44a5e213c..344ca2df4 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.ObdDecoder; @@ -29,7 +31,6 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.LinkedList; @@ -91,6 +92,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { public static final short MSG_SC_GPS_SLEEP = 0x4009; public static final short MSG_SC_FUEL = 0x400E; public static final short MSG_SC_AGPS_REQUEST = 0x5101; + public static final short MSG_SC_QUERY_RESPONSE = (short) 0xA002; public static final short MSG_SC_CURRENT_LOCATION = (short) 0xB001; public static final short MSG_CC_LOGIN = 0x4001; @@ -99,7 +101,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { public static final short MSG_CC_PETROL_CONTROL = 0x4583; public static final short MSG_CC_HEARTBEAT_RESPONSE = (short) 0x8206; - private Position readPosition(DeviceSession deviceSession, ChannelBuffer buf) { + private Position readPosition(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -109,10 +111,10 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); position.setTime(dateBuilder.getDate()); - double lat = buf.readUnsignedInt() / 3600000.0; - double lon = buf.readUnsignedInt() / 3600000.0; - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); - position.setCourse(buf.readUnsignedShort() * 0.1); + double lat = buf.readUnsignedIntLE() / 3600000.0; + double lon = buf.readUnsignedIntLE() / 3600000.0; + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE() * 0.1); int flags = buf.readUnsignedByte(); if ((flags & 0x02) == 0) { @@ -139,13 +141,13 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { return position; } - private void decodeObd(Position position, ChannelBuffer buf, boolean groups) { + private void decodeObd(Position position, ByteBuf buf, boolean groups) { int count = buf.readUnsignedByte(); int[] pids = new int[count]; for (int i = 0; i < count; i++) { - pids[i] = buf.readUnsignedShort() & 0xff; + pids[i] = buf.readUnsignedShortLE() & 0xff; } if (groups) { @@ -160,10 +162,10 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { value = buf.readUnsignedByte(); break; case 2: - value = buf.readUnsignedShort(); + value = buf.readUnsignedShortLE(); break; case 4: - value = buf.readInt(); + value = buf.readIntLE(); break; default: value = 0; @@ -173,21 +175,21 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeStat(Position position, ChannelBuffer buf) { + private void decodeStat(Position position, ByteBuf buf) { - buf.readUnsignedInt(); // ACC ON time - buf.readUnsignedInt(); // UTC time - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); - buf.readUnsignedShort(); // current fuel consumption - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + buf.readUnsignedIntLE(); // ACC ON time + buf.readUnsignedIntLE(); // UTC time + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedIntLE()); + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedIntLE()); + buf.readUnsignedShortLE(); // current fuel consumption + position.set(Position.KEY_STATUS, buf.readUnsignedIntLE()); buf.skipBytes(8); } private void sendResponse( Channel channel, SocketAddress remoteAddress, - int version, ChannelBuffer id, short type, ChannelBuffer content) { + int version, ByteBuf id, short type, ByteBuf content) { if (channel != null) { int length = 2 + 2 + 1 + id.readableBytes() + 2 + 2 + 2; @@ -195,41 +197,42 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { length += content.readableBytes(); } - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, length); + ByteBuf response = Unpooled.buffer(length); response.writeByte('@'); response.writeByte('@'); - response.writeShort(length); + response.writeShortLE(length); response.writeByte(version); response.writeBytes(id); - response.writeShort(ChannelBuffers.swapShort(type)); + response.writeShort(type); if (content != null) { response.writeBytes(content); + content.release(); } - response.writeShort( - Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(0, response.writerIndex()))); + response.writeShortLE( + Checksum.crc16(Checksum.CRC16_X25, response.nioBuffer(0, response.writerIndex()))); response.writeByte(0x0D); response.writeByte(0x0A); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } private void sendResponse( - Channel channel, SocketAddress remoteAddress, ChannelBuffer id, short type) { + Channel channel, SocketAddress remoteAddress, ByteBuf id, short type) { if (channel != null) { int length = 2 + 2 + id.readableBytes() + 2 + 4 + 8 + 2 + 2; - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, length); + ByteBuf response = Unpooled.buffer(length); response.writeByte('@'); response.writeByte('@'); - response.writeShort(length); + response.writeShortLE(length); response.writeBytes(id); - response.writeShort(ChannelBuffers.swapShort(type)); - response.writeInt(0); + response.writeShort(type); + response.writeIntLE(0); for (int i = 0; i < 8; i++) { response.writeByte(0xff); } - response.writeShort( - Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(0, response.writerIndex()))); + response.writeShortLE( + Checksum.crc16(Checksum.CRC16_X25, response.nioBuffer(0, response.writerIndex()))); response.writeByte(0x0D); response.writeByte(0x0A); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -250,9 +253,21 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { case 0x05: position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); break; + case 0x06: + position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + break; + case 0x07: + position.set(Position.KEY_ALARM, Position.ALARM_TOW); + break; + case 0x08: + position.set(Position.KEY_ALARM, Position.ALARM_HIGH_RPM); + break; case 0x09: position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); break; + case 0x0B: + position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + break; case 0x0C: position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); break; @@ -271,8 +286,8 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } private Object decodeSc( - Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, - int version, ChannelBuffer id, int type, DeviceSession deviceSession) { + Channel channel, SocketAddress remoteAddress, ByteBuf buf, + int version, ByteBuf id, short type, DeviceSession deviceSession) { if (type == MSG_SC_HEARTBEAT) { @@ -282,28 +297,28 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION || type == MSG_SC_FUEL) { if (type == MSG_SC_LOGIN) { - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 10); - response.writeInt(0xFFFFFFFF); - response.writeShort(0); - response.writeInt((int) (System.currentTimeMillis() / 1000)); + ByteBuf response = Unpooled.buffer(10); + response.writeIntLE(0xFFFFFFFF); + response.writeShortLE(0); + response.writeIntLE((int) (System.currentTimeMillis() / 1000)); sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response); } if (type == MSG_SC_GPS) { buf.readUnsignedByte(); // historical } else if (type == MSG_SC_ALARM) { - buf.readUnsignedInt(); // alarm + buf.readUnsignedIntLE(); // alarm } else if (type == MSG_SC_CURRENT_LOCATION) { - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); } - buf.readUnsignedInt(); // ACC ON time - buf.readUnsignedInt(); // UTC time - long odometer = buf.readUnsignedInt(); - long tripOdometer = buf.readUnsignedInt(); - long fuelConsumption = buf.readUnsignedInt(); - buf.readUnsignedShort(); // current fuel consumption - long status = buf.readUnsignedInt(); + buf.readUnsignedIntLE(); // ACC ON time + buf.readUnsignedIntLE(); // UTC time + long odometer = buf.readUnsignedIntLE(); + long tripOdometer = buf.readUnsignedIntLE(); + long fuelConsumption = buf.readUnsignedIntLE(); + buf.readUnsignedShortLE(); // current fuel consumption + long status = buf.readUnsignedIntLE(); buf.skipBytes(8); int count = buf.readUnsignedByte(); @@ -327,13 +342,13 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { for (Position position : positions) { decodeAlarm(position, alarm); } - buf.readUnsignedShort(); // description - buf.readUnsignedShort(); // threshold + buf.readUnsignedShortLE(); // description + buf.readUnsignedShortLE(); // threshold } } } else if (type == MSG_SC_FUEL) { for (Position position : positions) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); } } @@ -343,7 +358,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_SC_GPS_SLEEP) { - buf.readUnsignedInt(); // device time + buf.readUnsignedIntLE(); // device time return readPosition(deviceSession, buf); @@ -357,7 +372,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); - buf.readUnsignedShort(); // sample rate + buf.readUnsignedShortLE(); // sample rate decodeObd(position, buf, true); return position; @@ -369,7 +384,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); buf.readUnsignedByte(); // flag - position.add(ObdDecoder.decodeCodes(ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedByte())))); + position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())))); return position; @@ -391,7 +406,29 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + + return position; + + } else if (type == MSG_SC_QUERY_RESPONSE) { + + Position position = createPosition(deviceSession); + + buf.readUnsignedShortLE(); // index + buf.readUnsignedByte(); // response count + buf.readUnsignedByte(); // response index + + int failureCount = buf.readUnsignedByte(); + for (int i = 0; i < failureCount; i++) { + buf.readUnsignedShortLE(); // tag + } + + int successCount = buf.readUnsignedByte(); + for (int i = 0; i < successCount; i++) { + buf.readUnsignedShortLE(); // tag + position.set(Position.KEY_RESULT, + buf.readSlice(buf.readUnsignedShortLE()).toString(StandardCharsets.US_ASCII)); + } return position; @@ -401,8 +438,8 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } private Object decodeCc( - Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, - int version, ChannelBuffer id, int type, DeviceSession deviceSession) { + Channel channel, SocketAddress remoteAddress, ByteBuf buf, + int version, ByteBuf id, short type, DeviceSession deviceSession) { if (type == MSG_CC_HEARTBEAT) { @@ -416,16 +453,16 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { Position position = readPosition(deviceSession, buf); - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_STATUS, buf.readUnsignedIntLE()); position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); buf.readUnsignedByte(); // geo-fencing id buf.readUnsignedByte(); // geo-fencing flags buf.readUnsignedByte(); // additional flags position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); positions.add(position); } @@ -438,9 +475,9 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { Position position = readPosition(deviceSession, buf); - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_STATUS, buf.readUnsignedIntLE()); position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); buf.readUnsignedByte(); // geo-fencing id buf.readUnsignedByte(); // geo-fencing flags @@ -458,8 +495,8 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } private Object decodeMpip( - Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, - int version, ChannelBuffer id, int type, DeviceSession deviceSession) { + Channel channel, SocketAddress remoteAddress, ByteBuf buf, + int version, ByteBuf id, short type, DeviceSession deviceSession) { if (type == 0x4001) { @@ -471,8 +508,8 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, remoteAddress, id, (short) 0x1001); - buf.readUnsignedInt(); // index - buf.readUnsignedInt(); // unix time + buf.readUnsignedIntLE(); // index + buf.readUnsignedIntLE(); // unix time buf.readUnsignedByte(); return readPosition(deviceSession, buf); @@ -502,18 +539,18 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - int header = buf.readUnsignedShort(); - buf.readUnsignedShort(); // length + int header = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // length int version = -1; if (header == 0x4040) { version = buf.readUnsignedByte(); } - ChannelBuffer id = buf.readBytes(20); - int type = ChannelBuffers.swapShort(buf.readShort()); + ByteBuf id = buf.readSlice(20); + short type = buf.readShort(); DeviceSession deviceSession = getDeviceSession( channel, remoteAddress, id.toString(StandardCharsets.US_ASCII).trim()); diff --git a/src/org/traccar/protocol/CastelProtocolEncoder.java b/src/org/traccar/protocol/CastelProtocolEncoder.java index 806dac19e..dde8ac11f 100644 --- a/src/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/org/traccar/protocol/CastelProtocolEncoder.java @@ -15,37 +15,36 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; public class CastelProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(long deviceId, short type, ChannelBuffer content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { + ByteBuf buf = Unpooled.buffer(0); String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); buf.writeByte('@'); buf.writeByte('@'); - buf.writeShort(2 + 2 + 1 + 20 + 2 + content.readableBytes() + 2 + 2); // length + buf.writeShortLE(2 + 2 + 1 + 20 + 2 + content.readableBytes() + 2 + 2); // length buf.writeByte(1); // protocol version buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII)); buf.writeZero(20 - uniqueId.length()); - buf.writeShort(ChannelBuffers.swapShort(type)); + buf.writeShort(type); buf.writeBytes(content); - buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.toByteBuffer())); + buf.writeShortLE(Checksum.crc16(Checksum.CRC16_X25, buf.nioBuffer())); buf.writeByte('\r'); buf.writeByte('\n'); @@ -55,7 +54,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - ChannelBuffer content = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf content = Unpooled.buffer(0); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: content.writeByte(1); diff --git a/src/org/traccar/protocol/CautelaProtocol.java b/src/org/traccar/protocol/CautelaProtocol.java index 89ab7a1d0..dc5c82193 100644 --- a/src/org/traccar/protocol/CautelaProtocol.java +++ b/src/org/traccar/protocol/CautelaProtocol.java @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class CautelaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/CautelaProtocolDecoder.java b/src/org/traccar/protocol/CautelaProtocolDecoder.java index d7bf4fb51..ce231591e 100644 --- a/src/org/traccar/protocol/CautelaProtocolDecoder.java +++ b/src/org/traccar/protocol/CautelaProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -51,7 +51,7 @@ public class CautelaProtocolDecoder extends BaseProtocolDecoder { return null; } - String type = parser.next(); + parser.next(); // type DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { diff --git a/src/org/traccar/protocol/CellocatorFrameDecoder.java b/src/org/traccar/protocol/CellocatorFrameDecoder.java index b4708f5db..986dc75ec 100644 --- a/src/org/traccar/protocol/CellocatorFrameDecoder.java +++ b/src/org/traccar/protocol/CellocatorFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,29 +15,24 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; import org.traccar.helper.Log; -public class CellocatorFrameDecoder extends FrameDecoder { +public class CellocatorFrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_MINIMUM_LENGTH = 15; @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - // Check minimum length - int available = buf.readableBytes(); - if (available < MESSAGE_MINIMUM_LENGTH) { + if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { return null; } - // Size depending on message type int length = 0; int type = buf.getUnsignedByte(4); switch (type) { @@ -51,8 +46,8 @@ public class CellocatorFrameDecoder extends FrameDecoder { length = 70; break; case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL: - if (available >= 19) { - length = 19 + buf.getUnsignedShort(16); + if (buf.readableBytes() >= 19) { + length = 19 + buf.getUnsignedShortLE(16); } break; case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR: @@ -63,9 +58,8 @@ public class CellocatorFrameDecoder extends FrameDecoder { break; } - // Read packet - if (length > 0 && available >= length) { - return buf.readBytes(length); + if (length > 0 && buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/CellocatorProtocol.java b/src/org/traccar/protocol/CellocatorProtocol.java index 4a20bc977..bf186e67f 100644 --- a/src/org/traccar/protocol/CellocatorProtocol.java +++ b/src/org/traccar/protocol/CellocatorProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class CellocatorProtocol extends BaseProtocol { @@ -35,26 +32,21 @@ public class CellocatorProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CellocatorFrameDecoder()); pipeline.addLast("objectEncoder", new CellocatorProtocolEncoder()); pipeline.addLast("objectDecoder", new CellocatorProtocolDecoder(CellocatorProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); - - server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { + }); + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new CellocatorProtocolEncoder()); pipeline.addLast("objectDecoder", new CellocatorProtocolDecoder(CellocatorProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/org/traccar/protocol/CellocatorProtocolDecoder.java index 67db9aa7d..30319eaee 100644 --- a/src/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,17 +15,17 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; public class CellocatorProtocolDecoder extends BaseProtocolDecoder { @@ -44,27 +44,27 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { private byte commandCount; private void sendReply(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) { - ChannelBuffer reply = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 28); - reply.writeByte('M'); - reply.writeByte('C'); - reply.writeByte('G'); - reply.writeByte('P'); - reply.writeByte(MSG_SERVER_ACKNOWLEDGE); - reply.writeInt((int) deviceId); - reply.writeByte(commandCount++); - reply.writeInt(0); // authentication code - reply.writeByte(0); - reply.writeByte(packetNumber); - reply.writeZero(11); - - byte checksum = 0; - for (int i = 4; i < 27; i++) { - checksum += reply.getByte(i); - } - reply.writeByte(checksum); - if (channel != null) { - channel.write(reply, remoteAddress); + ByteBuf reply = Unpooled.buffer(28); + reply.writeByte('M'); + reply.writeByte('C'); + reply.writeByte('G'); + reply.writeByte('P'); + reply.writeByte(MSG_SERVER_ACKNOWLEDGE); + reply.writeIntLE((int) deviceId); + reply.writeByte(commandCount++); + reply.writeIntLE(0); // authentication code + reply.writeByte(0); + reply.writeByte(packetNumber); + reply.writeZero(11); + + byte checksum = 0; + for (int i = 4; i < 27; i++) { + checksum += reply.getByte(i); + } + reply.writeByte(checksum); + + channel.writeAndFlush(new NetworkMessage(reply, remoteAddress)); } } @@ -85,14 +85,14 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(4); // system code int type = buf.readUnsignedByte(); - long deviceUniqueId = buf.readUnsignedInt(); + long deviceUniqueId = buf.readUnsignedIntLE(); if (type != MSG_CLIENT_SERIAL) { - buf.readUnsignedShort(); // communication control + buf.readUnsignedShortLE(); // communication control } byte packetNumber = buf.readByte(); @@ -121,17 +121,17 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("mode", buf.readUnsignedByte()); - position.set(Position.PREFIX_IO + 1, buf.readUnsignedInt()); + position.set(Position.PREFIX_IO + 1, buf.readUnsignedIntLE()); operator <<= 8; operator += buf.readUnsignedByte(); position.set(Position.KEY_OPERATOR, operator); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedIntLE()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedMediumLE()); buf.skipBytes(6); // multi-purpose data - position.set(Position.KEY_GPS, buf.readUnsignedShort()); + position.set(Position.KEY_GPS, buf.readUnsignedShortLE()); position.set("locationStatus", buf.readUnsignedByte()); position.set("mode1", buf.readUnsignedByte()); position.set("mode2", buf.readUnsignedByte()); @@ -139,15 +139,15 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.setValid(true); - position.setLongitude(buf.readInt() / Math.PI * 180 / 100000000); - position.setLatitude(buf.readInt() / Math.PI * 180 / 100000000.0); - position.setAltitude(buf.readInt() * 0.01); - position.setSpeed(UnitsConverter.knotsFromMps(buf.readInt() * 0.01)); - position.setCourse(buf.readUnsignedShort() / Math.PI * 180.0 / 1000.0); + position.setLongitude(buf.readIntLE() / Math.PI * 180 / 100000000); + position.setLatitude(buf.readIntLE() / Math.PI * 180 / 100000000.0); + position.setAltitude(buf.readIntLE() * 0.01); + position.setSpeed(UnitsConverter.knotsFromMps(buf.readIntLE() * 0.01)); + position.setCourse(buf.readUnsignedShortLE() / Math.PI * 180.0 / 1000.0); DateBuilder dateBuilder = new DateBuilder() .setTimeReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedShort()); + .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedShortLE()); position.setTime(dateBuilder.getDate()); return position; diff --git a/src/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/org/traccar/protocol/CellocatorProtocolEncoder.java index bb143d349..4eef42128 100644 --- a/src/org/traccar/protocol/CellocatorProtocolEncoder.java +++ b/src/org/traccar/protocol/CellocatorProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,34 +15,32 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.ByteOrder; - public class CellocatorProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(long deviceId, int command, int data1, int data2) { + private ByteBuf encodeContent(long deviceId, int command, int data1, int data2) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf buf = Unpooled.buffer(0); buf.writeByte('M'); buf.writeByte('C'); buf.writeByte('G'); buf.writeByte('P'); buf.writeByte(0); - buf.writeInt(Integer.parseInt(getUniqueId(deviceId))); + buf.writeIntLE(Integer.parseInt(getUniqueId(deviceId))); buf.writeByte(0); // command numerator - buf.writeInt(0); // authentication code + buf.writeIntLE(0); // authentication code buf.writeByte(command); buf.writeByte(command); buf.writeByte(data1); buf.writeByte(data1); buf.writeByte(data2); buf.writeByte(data2); - buf.writeInt(0); // command specific data + buf.writeIntLE(0); // command specific data byte checksum = 0; for (int i = 4; i < buf.writerIndex(); i++) { diff --git a/src/org/traccar/protocol/CguardProtocol.java b/src/org/traccar/protocol/CguardProtocol.java index 460bd331f..5d2ffb6fd 100644 --- a/src/org/traccar/protocol/CguardProtocol.java +++ b/src/org/traccar/protocol/CguardProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class CguardProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/CguardProtocolDecoder.java b/src/org/traccar/protocol/CguardProtocolDecoder.java index 2e20537c8..806f500ab 100644 --- a/src/org/traccar/protocol/CguardProtocolDecoder.java +++ b/src/org/traccar/protocol/CguardProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/CityeasyProtocol.java b/src/org/traccar/protocol/CityeasyProtocol.java index 7e5ca0ba0..82b33e0f4 100644 --- a/src/org/traccar/protocol/CityeasyProtocol.java +++ b/src/org/traccar/protocol/CityeasyProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,9 +36,9 @@ public class CityeasyProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast("objectEncoder", new CityeasyProtocolEncoder()); pipeline.addLast("objectDecoder", new CityeasyProtocolDecoder(CityeasyProtocol.this)); diff --git a/src/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/org/traccar/protocol/CityeasyProtocolDecoder.java index 7a1d8119d..a66b9adb3 100644 --- a/src/org/traccar/protocol/CityeasyProtocolDecoder.java +++ b/src/org/traccar/protocol/CityeasyProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Checksum; @@ -69,12 +69,12 @@ public class CityeasyProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readUnsignedShort(); // length - String imei = ChannelBuffers.hexDump(buf.readBytes(7)); + String imei = ByteBufUtil.hexDump(buf.readSlice(7)); DeviceSession deviceSession = getDeviceSession( channel, remoteAddress, imei, imei + Checksum.luhn(Long.parseLong(imei))); if (deviceSession == null) { diff --git a/src/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/org/traccar/protocol/CityeasyProtocolEncoder.java index 387926e03..e143563f0 100644 --- a/src/org/traccar/protocol/CityeasyProtocolEncoder.java +++ b/src/org/traccar/protocol/CityeasyProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -17,8 +17,8 @@ package org.traccar.protocol; import java.util.TimeZone; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.Log; @@ -26,9 +26,9 @@ import org.traccar.model.Command; public class CityeasyProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(int type, ChannelBuffer content) { + private ByteBuf encodeContent(int type, ByteBuf content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte('S'); buf.writeByte('S'); @@ -36,7 +36,7 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(type); buf.writeBytes(content); buf.writeInt(0x0B); - buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.toByteBuffer())); + buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.nioBuffer())); buf.writeByte('\r'); buf.writeByte('\n'); @@ -46,7 +46,7 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: diff --git a/src/org/traccar/protocol/ContinentalProtocol.java b/src/org/traccar/protocol/ContinentalProtocol.java index e2b1226cf..540128120 100644 --- a/src/org/traccar/protocol/ContinentalProtocol.java +++ b/src/org/traccar/protocol/ContinentalProtocol.java @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,10 +30,10 @@ public class ContinentalProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast("objectDecoder", new ContinentalProtocolDecoder(ContinentalProtocol.this)); } }); diff --git a/src/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/org/traccar/protocol/ContinentalProtocolDecoder.java index 2138eb39e..20134fc1f 100644 --- a/src/org/traccar/protocol/ContinentalProtocolDecoder.java +++ b/src/org/traccar/protocol/ContinentalProtocolDecoder.java @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -40,13 +41,14 @@ public class ContinentalProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readUnsignedShort(); // length buf.readUnsignedByte(); // software version - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); + long serialNumber = buf.readUnsignedInt(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(serialNumber)); if (deviceSession == null) { return null; } @@ -76,13 +78,25 @@ public class ContinentalProtocolDecoder extends BaseProtocolDecoder { position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000L)); position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + + int input = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); buf.readUnsignedShort(); // reserved + if (buf.readableBytes() > 4) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + + if (buf.readableBytes() > 4) { + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(buf.readUnsignedInt())); + } + return position; } diff --git a/src/org/traccar/protocol/CradlepointProtocol.java b/src/org/traccar/protocol/CradlepointProtocol.java index 6ed54aa17..51de43bd9 100644 --- a/src/org/traccar/protocol/CradlepointProtocol.java +++ b/src/org/traccar/protocol/CradlepointProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class CradlepointProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index f74830756..222f73ec3 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -83,9 +83,9 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { position.set("carrid", parser.next()); position.set("serdis", parser.next()); - position.set("rsrp", parser.next()); - position.set("dbm", parser.next()); - position.set("rsrq", parser.next()); + position.set("rsrp", parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set("rsrq", parser.nextInt()); position.set("ecio", parser.next()); return position; diff --git a/src/org/traccar/protocol/DishaProtocol.java b/src/org/traccar/protocol/DishaProtocol.java index 53ba36004..1e746f270 100644 --- a/src/org/traccar/protocol/DishaProtocol.java +++ b/src/org/traccar/protocol/DishaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class DishaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/DishaProtocolDecoder.java b/src/org/traccar/protocol/DishaProtocolDecoder.java index a4e567b34..994bf6828 100644 --- a/src/org/traccar/protocol/DishaProtocolDecoder.java +++ b/src/org/traccar/protocol/DishaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/DmtHttpProtocol.java b/src/org/traccar/protocol/DmtHttpProtocol.java index 2378441ba..ee369dca0 100644 --- a/src/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/org/traccar/protocol/DmtHttpProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,12 +32,12 @@ public class DmtHttpProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(65535)); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(65535)); pipeline.addLast("objectDecoder", new DmtHttpProtocolDecoder(DmtHttpProtocol.this)); } }); diff --git a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java index 200a20759..bfe7d26a7 100644 --- a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -46,9 +46,9 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; + FullHttpRequest request = (FullHttpRequest) msg; JsonObject root = Json.createReader( - new StringReader(request.getContent().toString(StandardCharsets.US_ASCII))).readObject(); + new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); diff --git a/src/org/traccar/protocol/DmtProtocol.java b/src/org/traccar/protocol/DmtProtocol.java index 18bb1524a..3df261443 100644 --- a/src/org/traccar/protocol/DmtProtocol.java +++ b/src/org/traccar/protocol/DmtProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class DmtProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast("objectDecoder", new DmtProtocolDecoder(DmtProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java index 30a6ae13a..613b8cddd 100644 --- a/src/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtProtocolDecoder.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; @@ -50,20 +50,21 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_CANNED_REQUEST_2 = 0x22; public static final int MSG_CANNED_RESPONSE_2 = 0x23; - private void sendResponse(Channel channel, int type, ChannelBuffer content) { + private void sendResponse(Channel channel, int type, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(); response.writeByte(0x02); response.writeByte(0x55); // header response.writeByte(type); - response.writeShort(content != null ? content.readableBytes() : 0); + response.writeShortLE(content != null ? content.readableBytes() : 0); if (content != null) { response.writeBytes(content); + content.release(); } - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } - private List<Position> decodeFixed64(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List<Position> decodeFixed64(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -78,9 +79,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { buf.readByte(); // type - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - long time = buf.readUnsignedInt(); + long time = buf.readUnsignedIntLE(); position.setTime(new DateBuilder() .setYear((int) (2000 + (time & 0x3F))) .setMonth((int) (time >> 6) & 0xF) @@ -90,39 +91,39 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { .setSecond((int) (time >> 26) & 0x3F) .getDate()); - position.setLongitude(buf.readInt() * 0.0000001); - position.setLatitude(buf.readInt() * 0.0000001); - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShortLE())); position.setCourse(buf.readUnsignedByte() * 2); - position.setAltitude(buf.readShort()); + position.setAltitude(buf.readShortLE()); - buf.readUnsignedShort(); // position accuracy + buf.readUnsignedShortLE(); // position accuracy buf.readUnsignedByte(); // speed accuracy position.set(Position.KEY_EVENT, buf.readUnsignedByte()); position.setValid(BitUtil.check(buf.readByte(), 0)); - position.set(Position.KEY_INPUT, buf.readUnsignedInt()); - position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + position.set(Position.KEY_INPUT, buf.readUnsignedIntLE()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); for (int i = 1; i <= 5; i++) { - position.set(Position.PREFIX_ADC + i, buf.readShort()); + position.set(Position.PREFIX_ADC + i, buf.readShortLE()); } position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - buf.readShort(); // accelerometer x - buf.readShort(); // accelerometer y - buf.readShort(); // accelerometer z + buf.readShortLE(); // accelerometer x + buf.readShortLE(); // accelerometer y + buf.readShortLE(); // accelerometer z buf.skipBytes(8); // device id - position.set(Position.KEY_PDOP, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_PDOP, buf.readUnsignedShortLE() * 0.01); buf.skipBytes(2); // reserved - buf.readUnsignedShort(); // checksum + buf.readUnsignedShortLE(); // checksum positions.add(position); } @@ -130,7 +131,7 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { return positions; } - private List<Position> decodeStandard(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List<Position> decodeStandard(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -139,15 +140,15 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { List<Position> positions = new LinkedList<>(); - while (buf.readable()) { - int recordEnd = buf.readerIndex() + buf.readUnsignedShort(); + while (buf.isReadable()) { + int recordEnd = buf.readerIndex() + buf.readUnsignedShortLE(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013 + position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedIntLE() * 1000)); // since 1 Jan 2013 position.set(Position.KEY_EVENT, buf.readUnsignedByte()); @@ -155,15 +156,15 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { int fieldId = buf.readUnsignedByte(); int fieldLength = buf.readUnsignedByte(); - int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength); + int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShortLE() : fieldLength); if (fieldId == 0) { - position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - position.setAltitude(buf.readShort()); - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); + position.setFixTime(new Date(1356998400000L + buf.readUnsignedIntLE() * 1000)); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setAltitude(buf.readShortLE()); + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShortLE())); buf.readUnsignedByte(); // speed accuracy @@ -176,9 +177,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { } else if (fieldId == 2) { - int input = buf.readInt(); - int output = buf.readUnsignedShort(); - int status = buf.readUnsignedShort(); + int input = buf.readIntLE(); + int output = buf.readUnsignedShortLE(); + int status = buf.readUnsignedShortLE(); position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); @@ -191,19 +192,19 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { while (buf.readerIndex() < fieldEnd) { switch (buf.readUnsignedByte()) { case 1: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); break; case 2: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); break; case 3: - position.set(Position.KEY_DEVICE_TEMP, buf.readShort() * 0.01); + position.set(Position.KEY_DEVICE_TEMP, buf.readShortLE() * 0.01); break; case 4: - position.set(Position.KEY_RSSI, buf.readUnsignedShort()); + position.set(Position.KEY_RSSI, buf.readUnsignedShortLE()); break; case 5: - position.set("solarPower", buf.readUnsignedShort() * 0.001); + position.set("solarPower", buf.readUnsignedShortLE() * 0.001); break; default: break; @@ -230,40 +231,40 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte(); - int length = buf.readUnsignedShort(); + int length = buf.readUnsignedShortLE(); if (type == MSG_HELLO) { - buf.readUnsignedInt(); // device serial number + buf.readUnsignedIntLE(); // device serial number DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(); if (length == 51) { response.writeByte(0); // reserved - response.writeInt(0); // reserved + response.writeIntLE(0); // reserved } else { - response.writeInt((int) ((System.currentTimeMillis() - 1356998400000L) / 1000)); - response.writeInt(deviceSession != null ? 0 : 1); // flags + response.writeIntLE((int) ((System.currentTimeMillis() - 1356998400000L) / 1000)); + response.writeIntLE(deviceSession != null ? 0 : 1); // flags } sendResponse(channel, MSG_HELLO_RESPONSE, response); } else if (type == MSG_COMMIT) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(0); response.writeByte(1); // flags (success) sendResponse(channel, MSG_COMMIT_RESPONSE, response); } else if (type == MSG_CANNED_REQUEST_1) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(0); response.writeBytes(new byte[12]); sendResponse(channel, MSG_CANNED_RESPONSE_1, response); diff --git a/src/org/traccar/protocol/DwayProtocol.java b/src/org/traccar/protocol/DwayProtocol.java index 151d3fe01..d9af5bd02 100644 --- a/src/org/traccar/protocol/DwayProtocol.java +++ b/src/org/traccar/protocol/DwayProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class DwayProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/DwayProtocolDecoder.java b/src/org/traccar/protocol/DwayProtocolDecoder.java index 8ddd62b83..f2e1ad710 100644 --- a/src/org/traccar/protocol/DwayProtocolDecoder.java +++ b/src/org/traccar/protocol/DwayProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -61,7 +62,7 @@ public class DwayProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; if (sentence.equals("AA55,HB")) { if (channel != null) { - channel.write("55AA,HB,OK\r\n"); + channel.writeAndFlush(new NetworkMessage("55AA,HB,OK\r\n", remoteAddress)); } return null; } diff --git a/src/org/traccar/protocol/EasyTrackProtocol.java b/src/org/traccar/protocol/EasyTrackProtocol.java index eeed07129..5e1bb48be 100644 --- a/src/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/org/traccar/protocol/EasyTrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class EasyTrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "#", "\r\n")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java index 50b21841b..243b5f55d 100644 --- a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -54,6 +54,31 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private String decodeAlarm(long status) { + if ((status & 0x02000000) != 0) { + return Position.ALARM_GEOFENCE_ENTER; + } + if ((status & 0x04000000) != 0) { + return Position.ALARM_GEOFENCE_EXIT; + } + if ((status & 0x08000000) != 0) { + return Position.ALARM_LOW_BATTERY; + } + if ((status & 0x20000000) != 0) { + return Position.ALARM_VIBRATION; + } + if ((status & 0x80000000) != 0) { + return Position.ALARM_OVERSPEED; + } + if ((status & 0x00010000) != 0) { + return Position.ALARM_SOS; + } + if ((status & 0x00040000) != 0) { + return Position.ALARM_POWER_CUT; + } + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -95,7 +120,10 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt(0) / 100.0)); position.setCourse(parser.nextHexInt(0) / 100.0); - position.set(Position.KEY_STATUS, parser.next()); + long status = parser.nextHexLong(); + position.set(Position.KEY_STATUS, status); + position.set(Position.KEY_ALARM, decodeAlarm(status)); + position.set("signal", parser.next()); position.set(Position.KEY_POWER, parser.nextDouble(0)); position.set("oil", parser.nextHexInt(0)); diff --git a/src/org/traccar/protocol/EelinkProtocol.java b/src/org/traccar/protocol/EelinkProtocol.java index 3d0a006de..0ad23fc14 100644 --- a/src/org/traccar/protocol/EelinkProtocol.java +++ b/src/org/traccar/protocol/EelinkProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -39,17 +37,17 @@ public class EelinkProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast("objectEncoder", new EelinkProtocolEncoder(false)); pipeline.addLast("objectDecoder", new EelinkProtocolDecoder(EelinkProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new EelinkProtocolEncoder(true)); pipeline.addLast("objectDecoder", new EelinkProtocolDecoder(EelinkProtocol.this)); } diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 0ed81c925..67e7f5127 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,12 +15,13 @@ */ 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.channel.socket.DatagramChannel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; +import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -62,8 +63,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, SocketAddress remoteAddress, String uniqueId, int type, int index) { if (channel != null) { - channel.write(EelinkProtocolEncoder.encodeContent( - channel instanceof DatagramChannel, uniqueId, type, index, null), remoteAddress); + channel.writeAndFlush(new NetworkMessage(EelinkProtocolEncoder.encodeContent( + channel instanceof DatagramChannel, uniqueId, type, index, null), remoteAddress)); } } @@ -113,7 +114,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, status); } - private Position decodeOld(DeviceSession deviceSession, ChannelBuffer buf, int type, int index) { + private Position decodeOld(DeviceSession deviceSession, ByteBuf buf, int type, int index) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -170,7 +171,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decodeNew(DeviceSession deviceSession, ChannelBuffer buf, int index) { + private Position decodeNew(DeviceSession deviceSession, ByteBuf buf, int type, int index) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -218,43 +219,59 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } - if (buf.readableBytes() >= 2) { + if (type == MSG_WARNING) { + + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + + } else if (type == MSG_REPORT) { + + buf.readUnsignedByte(); // report type + + } + + if (type == MSG_NORMAL || type == MSG_WARNING || type == MSG_REPORT) { + int status = buf.readUnsignedShort(); position.setValid(BitUtil.check(status, 0)); if (BitUtil.check(status, 1)) { position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); } position.set(Position.KEY_STATUS, status); - } - if (buf.readableBytes() >= 2) { - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); } - if (buf.readableBytes() >= 4) { - position.set(Position.PREFIX_ADC + 0, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - } + if (type == MSG_NORMAL) { - if (buf.readableBytes() >= 4) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + if (buf.readableBytes() >= 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + } - if (buf.readableBytes() >= 4) { - buf.readUnsignedShort(); // gsm counter - buf.readUnsignedShort(); // gps counter - } + if (buf.readableBytes() >= 4) { + position.set(Position.PREFIX_ADC + 0, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + } - if (buf.readableBytes() >= 4) { - position.set(Position.KEY_STEPS, buf.readUnsignedShort()); - buf.readUnsignedShort(); // walking time - } + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + + if (buf.readableBytes() >= 4) { + buf.readUnsignedShort(); // gsm counter + buf.readUnsignedShort(); // gps counter + } + + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_STEPS, buf.readUnsignedShort()); + buf.readUnsignedShort(); // walking time + } + + if (buf.readableBytes() >= 12) { + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() / 256.0); + position.set("humidity", buf.readUnsignedShort() * 0.1); + position.set("illuminance", buf.readUnsignedInt() / 256.0); + position.set("co2", buf.readUnsignedInt()); + } - if (buf.readableBytes() >= 12) { - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() / 256.0); - position.set("humidity", buf.readUnsignedShort() * 0.1); - position.set("illuminance", buf.readUnsignedInt() / 256.0); - position.set("co2", buf.readUnsignedInt()); } return position; @@ -278,7 +295,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { .number("(dd):(dd):(dd)") // time .compile(); - private Position decodeResult(DeviceSession deviceSession, ChannelBuffer buf, int index) { + private Position decodeResult(DeviceSession deviceSession, ByteBuf buf, int index) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -315,14 +332,14 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; String uniqueId = null; DeviceSession deviceSession; if (buf.getByte(0) == 'E' && buf.getByte(1) == 'L') { buf.skipBytes(2 + 2 + 2); // udp header - uniqueId = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + uniqueId = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); } else { deviceSession = getDeviceSession(channel, remoteAddress); @@ -340,7 +357,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_LOGIN) { if (deviceSession == null) { - getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(8)).substring(1)); + getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(buf.readSlice(8)).substring(1)); } } else { @@ -355,7 +372,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) { - return decodeNew(deviceSession, buf, index); + return decodeNew(deviceSession, buf, type, index); } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java index 4d2d86e68..64236ca4a 100644 --- a/src/org/traccar/protocol/EelinkProtocolEncoder.java +++ b/src/org/traccar/protocol/EelinkProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.helper.Log; @@ -41,13 +41,13 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { return sum; } - public static ChannelBuffer encodeContent( - boolean connectionless, String uniqueId, int type, int index, ChannelBuffer content) { + public static ByteBuf encodeContent( + boolean connectionless, String uniqueId, int type, int index, ByteBuf content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); if (connectionless) { - buf.writeBytes(ChannelBuffers.wrappedBuffer(DataConverter.parseHex('0' + uniqueId))); + buf.writeBytes(DataConverter.parseHex('0' + uniqueId)); } buf.writeByte(0x67); @@ -60,13 +60,13 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { buf.writeBytes(content); } - ChannelBuffer result = ChannelBuffers.dynamicBuffer(); + ByteBuf result = Unpooled.buffer(); if (connectionless) { result.writeByte('E'); result.writeByte('L'); result.writeShort(2 + buf.readableBytes()); // length - result.writeShort(checksum(buf.toByteBuffer())); + result.writeShort(checksum(buf.nioBuffer())); } result.writeBytes(buf); @@ -74,9 +74,9 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { return result; } - private ChannelBuffer encodeContent(long deviceId, String content) { + private ByteBuf encodeContent(long deviceId, String content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x01); // command buf.writeInt(0); // server id diff --git a/src/org/traccar/protocol/EgtsFrameDecoder.java b/src/org/traccar/protocol/EgtsFrameDecoder.java index 71ffc1811..84f1f11a7 100644 --- a/src/org/traccar/protocol/EgtsFrameDecoder.java +++ b/src/org/traccar/protocol/EgtsFrameDecoder.java @@ -15,28 +15,28 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class EgtsFrameDecoder extends FrameDecoder { +public class EgtsFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; } int headerLength = buf.getUnsignedByte(buf.readerIndex() + 3); - int frameLength = buf.getUnsignedShort(buf.readerIndex() + 5); + int frameLength = buf.getUnsignedShortLE(buf.readerIndex() + 5); int length = headerLength + frameLength + (frameLength > 0 ? 2 : 0); if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/EgtsProtocol.java b/src/org/traccar/protocol/EgtsProtocol.java index 0a57f0061..2bc2ec10d 100644 --- a/src/org/traccar/protocol/EgtsProtocol.java +++ b/src/org/traccar/protocol/EgtsProtocol.java @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class EgtsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new EgtsFrameDecoder()); pipeline.addLast("objectDecoder", new EgtsProtocolDecoder(EgtsProtocol.this)); } diff --git a/src/org/traccar/protocol/EgtsProtocolDecoder.java b/src/org/traccar/protocol/EgtsProtocolDecoder.java index d05504d81..45e191d1e 100644 --- a/src/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/org/traccar/protocol/EgtsProtocolDecoder.java @@ -15,14 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -33,6 +38,10 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int PT_RESPONSE = 0; + public static final int PT_APPDATA = 1; + public static final int PT_SIGNED_APPDATA = 2; + public static final int SERVICE_AUTH = 1; public static final int SERVICE_TELEDATA = 2; public static final int SERVICE_COMMANDS = 4; @@ -60,60 +69,138 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LIQUID_LEVEL_SENSOR = 27; public static final int MSG_PASSENGERS_COUNTERS = 28; + private int packetId; + + private void sendResponse( + Channel channel, int packetType, int index, int serviceType, int type, ByteBuf content) { + if (channel != null) { + + ByteBuf data = Unpooled.buffer(); + data.writeByte(type); + data.writeShortLE(content.readableBytes()); + data.writeBytes(content); + content.release(); + + ByteBuf record = Unpooled.buffer(); + if (packetType == PT_RESPONSE) { + record.writeShortLE(index); + record.writeByte(0); // success + } + record.writeShortLE(data.readableBytes()); + record.writeShortLE(0); + record.writeByte(0); // flags (possibly 1 << 6) + record.writeByte(serviceType); + record.writeByte(serviceType); + record.writeBytes(data); + data.release(); + int recordChecksum = Checksum.crc16(Checksum.CRC16_CCITT_FALSE, record.nioBuffer()); + + ByteBuf response = Unpooled.buffer(); + response.writeByte(1); // protocol version + response.writeByte(0); // security key id + response.writeByte(0); // flags + response.writeByte(5 + 2 + 2 + 2); // header length + response.writeByte(0); // encoding + response.writeShortLE(record.readableBytes()); + response.writeShortLE(packetId++); + response.writeByte(packetType); + response.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, response.nioBuffer())); + response.writeBytes(record); + record.release(); + response.writeShortLE(recordChecksum); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; + int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3)); - DeviceSession deviceSession = null; List<Position> positions = new LinkedList<>(); while (buf.readableBytes() > 2) { - int length = buf.readUnsignedShort(); - - buf.readUnsignedShort(); // index - + int length = buf.readUnsignedShortLE(); + int recordIndex = buf.readUnsignedShortLE(); int recordFlags = buf.readUnsignedByte(); if (BitUtil.check(recordFlags, 0)) { - String deviceId = String.valueOf(buf.readUnsignedInt()); - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress, deviceId); - } - } - - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress); + buf.readUnsignedIntLE(); // object id } if (BitUtil.check(recordFlags, 1)) { - buf.readUnsignedInt(); // event id + buf.readUnsignedIntLE(); // event id } if (BitUtil.check(recordFlags, 2)) { - buf.readUnsignedInt(); // time + buf.readUnsignedIntLE(); // time } - buf.readUnsignedByte(); // source service type + int serviceType = buf.readUnsignedByte(); buf.readUnsignedByte(); // recipient service type int recordEnd = buf.readerIndex() + length; Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + + ByteBuf response = Unpooled.buffer(); + response.writeShortLE(recordIndex); + response.writeByte(0); // success + sendResponse(channel, PT_RESPONSE, index, serviceType, MSG_RECORD_RESPONSE, response); while (buf.readerIndex() < recordEnd) { int type = buf.readUnsignedByte(); - int end = buf.readUnsignedShort() + buf.readerIndex(); + int end = buf.readUnsignedShortLE() + buf.readerIndex(); + + if (type == MSG_TERM_IDENTITY) { + + buf.readUnsignedIntLE(); // object id + int flags = buf.readUnsignedByte(); + + if (BitUtil.check(flags, 0)) { + buf.readUnsignedShortLE(); // home dispatcher identifier + } + if (BitUtil.check(flags, 1)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim()); + } + if (BitUtil.check(flags, 2)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); + } + if (BitUtil.check(flags, 3)) { + buf.skipBytes(3); // language identifier + } + if (BitUtil.check(flags, 5)) { + buf.skipBytes(3); // network identifier + } + if (BitUtil.check(flags, 6)) { + buf.readUnsignedShortLE(); // buffer size + } + if (BitUtil.check(flags, 7)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim()); + } - if (type == MSG_POS_DATA) { + response = Unpooled.buffer(); + response.writeByte(0); // success + sendResponse(channel, PT_APPDATA, 0, serviceType, MSG_RESULT_CODE, response); - position.setTime(new Date((buf.readUnsignedInt() + 1262304000) * 1000)); // since 2010-01-01 - position.setLatitude(buf.readUnsignedInt() * 90.0 / 0xFFFFFFFFL); - position.setLongitude(buf.readUnsignedInt() * 180.0 / 0xFFFFFFFFL); + } else if (type == MSG_POS_DATA) { + + position.setTime(new Date((buf.readUnsignedIntLE() + 1262304000) * 1000)); // since 2010-01-01 + position.setLatitude(buf.readUnsignedIntLE() * 90.0 / 0xFFFFFFFFL); + position.setLongitude(buf.readUnsignedIntLE() * 180.0 / 0xFFFFFFFFL); int flags = buf.readUnsignedByte(); position.setValid(BitUtil.check(flags, 0)); @@ -124,16 +211,16 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(-position.getLongitude()); } - int speed = buf.readUnsignedShort(); - position.setSpeed(BitUtil.to(speed, 14)); + int speed = buf.readUnsignedShortLE(); + position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speed, 14) * 0.1)); position.setCourse(buf.readUnsignedByte() + (BitUtil.check(speed, 15) ? 0x100 : 0)); - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 100); + position.set(Position.KEY_ODOMETER, buf.readUnsignedMediumLE() * 100); position.set(Position.KEY_INPUT, buf.readUnsignedByte()); position.set(Position.KEY_EVENT, buf.readUnsignedByte()); if (BitUtil.check(flags, 7)) { - position.setAltitude(buf.readMedium()); + position.setAltitude(buf.readMediumLE()); } } else if (type == MSG_EXT_POS_DATA) { @@ -141,13 +228,13 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { int flags = buf.readUnsignedByte(); if (BitUtil.check(flags, 0)) { - position.set(Position.KEY_VDOP, buf.readUnsignedShort()); + position.set(Position.KEY_VDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_PDOP, buf.readUnsignedShort()); + position.set(Position.KEY_PDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 3)) { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); @@ -166,7 +253,9 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { buf.readerIndex(end); } - positions.add(position); + if (serviceType == SERVICE_TELEDATA && deviceSession != null) { + positions.add(position); + } } return positions.isEmpty() ? null : positions; diff --git a/src/org/traccar/protocol/EnforaProtocol.java b/src/org/traccar/protocol/EnforaProtocol.java index 79cc47c0b..ebdb4a31b 100644 --- a/src/org/traccar/protocol/EnforaProtocol.java +++ b/src/org/traccar/protocol/EnforaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -36,9 +35,9 @@ public class EnforaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); pipeline.addLast("objectEncoder", new EnforaProtocolEncoder()); pipeline.addLast("objectDecoder", new EnforaProtocolDecoder(EnforaProtocol.this)); diff --git a/src/org/traccar/protocol/EnforaProtocolDecoder.java b/src/org/traccar/protocol/EnforaProtocolDecoder.java index c5500c3b3..d78be685f 100644 --- a/src/org/traccar/protocol/EnforaProtocolDecoder.java +++ b/src/org/traccar/protocol/EnforaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,15 +15,14 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBufferIndexFinder; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BufferUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.StringFinder; import org.traccar.model.Position; import java.net.SocketAddress; @@ -56,23 +55,22 @@ public class EnforaProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; // Find IMEI number - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new ChannelBufferIndexFinder() { - @Override - public boolean find(ChannelBuffer buffer, int guessedIndex) { - if (buffer.writerIndex() - guessedIndex >= IMEI_LENGTH) { - for (int i = 0; i < IMEI_LENGTH; i++) { - if (!Character.isDigit((char) buffer.getByte(guessedIndex + i))) { - return false; - } - } - return true; + int index = -1; + for (int i = buf.readerIndex(); i < buf.writerIndex() - IMEI_LENGTH; i++) { + index = i; + for (int j = i; j < i + IMEI_LENGTH; j++) { + if (!Character.isDigit((char) buf.getByte(j))) { + index = -1; + break; } - return false; } - }); + if (index > 0) { + break; + } + } if (index == -1) { return null; } @@ -84,7 +82,7 @@ public class EnforaProtocolDecoder extends BaseProtocolDecoder { } // Find NMEA sentence - int start = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("GPRMC")); + int start = BufferUtil.indexOf("GPRMC", buf); if (start == -1) { return null; } diff --git a/src/org/traccar/protocol/EnforaProtocolEncoder.java b/src/org/traccar/protocol/EnforaProtocolEncoder.java index 3dca1b9b3..a8fe53691 100644 --- a/src/org/traccar/protocol/EnforaProtocolEncoder.java +++ b/src/org/traccar/protocol/EnforaProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) * Copyright 2017 Jose Castellanos * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,8 +16,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -26,9 +26,9 @@ import java.nio.charset.StandardCharsets; public class EnforaProtocolEncoder extends StringProtocolEncoder { - private ChannelBuffer encodeContent(String content) { + private ByteBuf encodeContent(String content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeShort(content.length() + 6); buf.writeShort(0); // index diff --git a/src/org/traccar/protocol/EsealProtocol.java b/src/org/traccar/protocol/EsealProtocol.java new file mode 100644 index 000000000..54be201d1 --- /dev/null +++ b/src/org/traccar/protocol/EsealProtocol.java @@ -0,0 +1,52 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.model.Command; + +import java.util.List; + +public class EsealProtocol extends BaseProtocol { + + public EsealProtocol() { + super("eseal"); + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_ALARM_ARM, + Command.TYPE_ALARM_DISARM); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectEncoder", new EsealProtocolEncoder()); + pipeline.addLast("objectDecoder", new EsealProtocolDecoder(EsealProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/EsealProtocolDecoder.java b/src/org/traccar/protocol/EsealProtocolDecoder.java new file mode 100644 index 000000000..39c0d94c2 --- /dev/null +++ b/src/org/traccar/protocol/EsealProtocolDecoder.java @@ -0,0 +1,157 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class EsealProtocolDecoder extends BaseProtocolDecoder { + + private String config; + + public EsealProtocolDecoder(EsealProtocol protocol) { + super(protocol); + config = Context.getConfig().getString(getProtocolName() + ".config"); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("##S,") + .expression("[^,]+,") // device type + .number("(d+),") // device id + .number("d+,") // customer id + .expression("[^,]+,") // firmware version + .expression("([^,]+),") // type + .number("(d+),") // index + .number("(dddd)-(dd)-(dd),") // date + .number("(dd):(dd):(dd),") // time + .number("d+,") // interval + .expression("([AV]),") // validity + .number("(d+.d+)([NS]) ") // latitude + .number("(d+.d+)([EW]),") // longitude + .number("(d+),") // course + .number("(d+),") // speed + .expression("([^,]+),") // door + .number("(d+.d+),") // acceleration + .expression("([^,]+),") // nfc + .number("(d+.d+),") // battery + .number("(-?d+),") // rssi + .text("E##") + .compile(); + + private void sendResponse(Channel channel, String prefix, String type, String payload) { + if (channel != null) { + channel.writeAndFlush(new NetworkMessage( + prefix + type + "," + payload + ",E##\r\n", channel.remoteAddress())); + } + } + + private String decodeAlarm(String type) { + switch (type) { + case "Event-Door": + return Position.ALARM_DOOR; + case "Event-Shock": + return Position.ALARM_SHOCK; + case "Event-Drop": + return Position.ALARM_FALL_DOWN; + case "Event-Lock": + return Position.ALARM_LOCK; + case "Event-RC-Unlock": + return Position.ALARM_UNLOCK; + default: + return null; + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + Parser parser = new Parser(PATTERN, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + String type = parser.next(); + String prefix = sentence.substring(0, sentence.indexOf(type)); + int index = parser.nextInt(); + + position.set(Position.KEY_INDEX, index); + position.set(Position.KEY_ALARM, decodeAlarm(type)); + + switch (type) { + case "Startup": + sendResponse(channel, prefix, type + " ACK", index + "," + config); + break; + case "Normal": + case "Button-Normal": + case "Termination": + case "Event-Door": + case "Event-Shock": + case "Event-Drop": + case "Event-Lock": + case "Event-RC-Unlock": + sendResponse(channel, prefix, type + " ACK", String.valueOf(index)); + break; + default: + break; + } + + position.setTime(parser.nextDateTime()); + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setCourse(parser.nextInt()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + switch (parser.next()) { + case "Open": + position.set(Position.KEY_DOOR, true); + break; + case "Close": + position.set(Position.KEY_DOOR, false); + break; + default: + break; + } + + position.set(Position.KEY_ACCELERATION, parser.nextDouble()); + position.set("nfc", parser.next()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_RSSI, parser.nextInt()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/EsealProtocolEncoder.java b/src/org/traccar/protocol/EsealProtocolEncoder.java new file mode 100644 index 000000000..886bb80b1 --- /dev/null +++ b/src/org/traccar/protocol/EsealProtocolEncoder.java @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.StringProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +public class EsealProtocolEncoder extends StringProtocolEncoder { + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand( + command, "##S,eSeal,{%s},256,3.0.8,{%s},E##", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + case Command.TYPE_ALARM_ARM: + return formatCommand( + command, "##S,eSeal,{%s},256,3.0.8,RC-Power Control,Power OFF,E##", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM: + return formatCommand( + command, "##S,eSeal,{%s},256,3.0.8,RC-Unlock,E##", Command.KEY_UNIQUE_ID); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/EskyFrameDecoder.java b/src/org/traccar/protocol/EskyFrameDecoder.java index 3175698fd..da24c1273 100644 --- a/src/org/traccar/protocol/EskyFrameDecoder.java +++ b/src/org/traccar/protocol/EskyFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,24 +15,24 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class EskyFrameDecoder extends FrameDecoder { +public class EskyFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 'E')); int endIndex = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 'E'); if (endIndex > 0) { - return buf.readBytes(endIndex - buf.readerIndex()); + return buf.readRetainedSlice(endIndex - buf.readerIndex()); } else { - return buf.readBytes(buf.readableBytes()); // assume full frame + return buf.readRetainedSlice(buf.readableBytes()); // assume full frame } } diff --git a/src/org/traccar/protocol/EskyProtocol.java b/src/org/traccar/protocol/EskyProtocol.java index 4c1d11f7d..65dd607a3 100644 --- a/src/org/traccar/protocol/EskyProtocol.java +++ b/src/org/traccar/protocol/EskyProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class EskyProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new EskyFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java index 60ef4f846..712632ac3 100644 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; @@ -37,16 +37,18 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { .number("d+;") // index .number("(d+);") // imei .text("R;") // data type - .number("(d+)").text("+") // satellites + .number("(d+)[+;]") // satellites .number("(dd)(dd)(dd)") // date - .number("(dd)(dd)(dd)").text("+") // time - .number("(-?d+.d+)").text("+") // latitude - .number("(-?d+.d+)").text("+") // longitude - .number("(d+.d+)").text("+") // speed - .number("(d+)").text("+") // course - .text("0x").number("(d+)").text("+") // input - .number("(d+)").text("+") // message type - .number("(d+)").text("+") // odometer + .number("(dd)(dd)(dd)[+;]") // time + .number("(-?d+.d+)[+;]") // latitude + .number("(-?d+.d+)[+;]") // longitude + .number("(d+.d+)[+;]") // speed + .number("(d+)[+;]") // course + .groupBegin() + .text("0x").number("(d+)[+;]") // input + .number("(d+)[+;]") // message type + .number("(d+)[+;]") // odometer + .groupEnd("?") .number("(d+)") // voltage .any() .compile(); @@ -77,10 +79,13 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromMps(parser.nextDouble())); position.setCourse(parser.nextDouble()); - position.set(Position.KEY_INPUT, parser.nextHexInt()); - position.set(Position.KEY_EVENT, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextInt()); - position.set(Position.KEY_POWER, parser.nextInt()); + if (parser.hasNext(3)) { + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextInt()); + } + + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); return position; } diff --git a/src/org/traccar/protocol/ExtremTracProtocol.java b/src/org/traccar/protocol/ExtremTracProtocol.java index d9b178e23..e0c2876ca 100644 --- a/src/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/org/traccar/protocol/ExtremTracProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class ExtremTracProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/org/traccar/protocol/ExtremTracProtocolDecoder.java index 553720f1e..c214b4f5d 100644 --- a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java +++ b/src/org/traccar/protocol/ExtremTracProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/FifotrackProtocol.java b/src/org/traccar/protocol/FifotrackProtocol.java index f4ca450c0..6d42fc8fe 100644 --- a/src/org/traccar/protocol/FifotrackProtocol.java +++ b/src/org/traccar/protocol/FifotrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class FifotrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new FifotrackProtocolDecoder(FifotrackProtocol.this)); diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java index cb7a23315..b27368e3a 100644 --- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/FlespiProtocol.java b/src/org/traccar/protocol/FlespiProtocol.java index d22bd7ae0..4ac5d2ccd 100644 --- a/src/org/traccar/protocol/FlespiProtocol.java +++ b/src/org/traccar/protocol/FlespiProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,12 +32,12 @@ public class FlespiProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(Integer.MAX_VALUE)); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(Integer.MAX_VALUE)); pipeline.addLast("objectDecoder", new FlespiProtocolDecoder(FlespiProtocol.this)); } }); diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java index 526e10fa2..da5ba13e9 100644 --- a/src/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.model.Position; @@ -46,8 +46,8 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - JsonArray result = Json.createReader(new StringReader(request.getContent().toString(StandardCharsets.UTF_8))) + FullHttpRequest request = (FullHttpRequest) msg; + JsonArray result = Json.createReader(new StringReader(request.content().toString(StandardCharsets.UTF_8))) .readArray(); List<Position> positions = new LinkedList<>(); for (int i = 0; i < result.size(); i++) { diff --git a/src/org/traccar/protocol/FlexCommProtocol.java b/src/org/traccar/protocol/FlexCommProtocol.java index 5dba4421a..69bd99c79 100644 --- a/src/org/traccar/protocol/FlexCommProtocol.java +++ b/src/org/traccar/protocol/FlexCommProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.FixedLengthFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class FlexCommProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/org/traccar/protocol/FlexCommProtocolDecoder.java index 8bd4dcee0..3a1e23d20 100644 --- a/src/org/traccar/protocol/FlexCommProtocolDecoder.java +++ b/src/org/traccar/protocol/FlexCommProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -117,7 +118,7 @@ public class FlexCommProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, parser.nextInt() * 0.1); if (channel != null) { - channel.write("{01}"); + channel.writeAndFlush(new NetworkMessage("{01}", remoteAddress)); } return position; diff --git a/src/org/traccar/protocol/FlextrackProtocol.java b/src/org/traccar/protocol/FlextrackProtocol.java index 77e316d82..a94df710a 100644 --- a/src/org/traccar/protocol/FlextrackProtocol.java +++ b/src/org/traccar/protocol/FlextrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class FlextrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/org/traccar/protocol/FlextrackProtocolDecoder.java index 8f7525147..a6970ba86 100644 --- a/src/org/traccar/protocol/FlextrackProtocolDecoder.java +++ b/src/org/traccar/protocol/FlextrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -65,9 +66,9 @@ public class FlextrackProtocolDecoder extends BaseProtocolDecoder { .number("(d+)") // odometer .compile(); - private void sendAcknowledgement(Channel channel, String index) { + private void sendAcknowledgement(Channel channel, SocketAddress remoteAddress, String index) { if (channel != null) { - channel.write(index + ",ACK\r"); + channel.writeAndFlush(new NetworkMessage(index + ",ACK\r", remoteAddress)); } } @@ -84,7 +85,7 @@ public class FlextrackProtocolDecoder extends BaseProtocolDecoder { return null; } - sendAcknowledgement(channel, parser.next()); + sendAcknowledgement(channel, remoteAddress, parser.next()); String id = parser.next(); String iccid = parser.next(); @@ -106,7 +107,7 @@ public class FlextrackProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - sendAcknowledgement(channel, parser.next()); + sendAcknowledgement(channel, remoteAddress, parser.next()); position.setTime(parser.nextDateTime()); diff --git a/src/org/traccar/protocol/FoxProtocol.java b/src/org/traccar/protocol/FoxProtocol.java index 501bff4c4..6f312dc8e 100644 --- a/src/org/traccar/protocol/FoxProtocol.java +++ b/src/org/traccar/protocol/FoxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class FoxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "</fox>")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/FoxProtocolDecoder.java b/src/org/traccar/protocol/FoxProtocolDecoder.java index 16f8fce27..7ce57109d 100644 --- a/src/org/traccar/protocol/FoxProtocolDecoder.java +++ b/src/org/traccar/protocol/FoxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/FreedomProtocol.java b/src/org/traccar/protocol/FreedomProtocol.java index 5b4bf22ff..7ea09d25a 100644 --- a/src/org/traccar/protocol/FreedomProtocol.java +++ b/src/org/traccar/protocol/FreedomProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class FreedomProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/FreedomProtocolDecoder.java b/src/org/traccar/protocol/FreedomProtocolDecoder.java index 28456c617..95348ba11 100644 --- a/src/org/traccar/protocol/FreedomProtocolDecoder.java +++ b/src/org/traccar/protocol/FreedomProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/FreematicsProtocol.java b/src/org/traccar/protocol/FreematicsProtocol.java new file mode 100644 index 000000000..3bcd5bfd1 --- /dev/null +++ b/src/org/traccar/protocol/FreematicsProtocol.java @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class FreematicsProtocol extends BaseProtocol { + + public FreematicsProtocol() { + super("freematics"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new FreematicsProtocolDecoder(FreematicsProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/org/traccar/protocol/FreematicsProtocolDecoder.java new file mode 100644 index 000000000..2cab45189 --- /dev/null +++ b/src/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -0,0 +1,103 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; + +public class FreematicsProtocolDecoder extends BaseProtocolDecoder { + + public FreematicsProtocolDecoder(FreematicsProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + int startIndex = sentence.indexOf('#'); + int endIndex = sentence.indexOf('*'); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(0, startIndex)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setValid(true); + + DateBuilder dateBuilder = new DateBuilder(new Date()); + + for (String pair : sentence.substring(startIndex + 1, endIndex).split(",")) { + String[] data = pair.split("="); + int key = Integer.parseInt(data[0], 16); + String value = data[1]; + switch (key) { + case 0x11: + value = ("000000" + value).substring(value.length()); + dateBuilder.setDateReverse( + Integer.parseInt(value.substring(0, 2)), + Integer.parseInt(value.substring(2, 4)), + Integer.parseInt(value.substring(4))); + break; + case 0x10: + value = ("00000000" + value).substring(value.length()); + dateBuilder.setTime( + Integer.parseInt(value.substring(0, 2)), + Integer.parseInt(value.substring(2, 4)), + Integer.parseInt(value.substring(4, 6)), + Integer.parseInt(value.substring(6)) * 10); + break; + case 0xA: + position.setLatitude(Double.parseDouble(value)); + break; + case 0xB: + position.setLongitude(Double.parseDouble(value)); + break; + case 0xC: + position.setAltitude(Integer.parseInt(value)); + break; + case 0xD: + position.setLatitude(UnitsConverter.knotsFromKph(Integer.parseInt(value))); + break; + case 0xE: + position.setCourse(Integer.parseInt(value)); + break; + case 0xF: + position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + break; + default: + position.set(data[0], value); + break; + } + + } + + position.setTime(dateBuilder.getDate()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/GalileoFrameDecoder.java b/src/org/traccar/protocol/GalileoFrameDecoder.java index 6d02ce744..c23d26c83 100644 --- a/src/org/traccar/protocol/GalileoFrameDecoder.java +++ b/src/org/traccar/protocol/GalileoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,30 +15,26 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class GalileoFrameDecoder extends FrameDecoder { +public class GalileoFrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_MINIMUM_LENGTH = 5; @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - // Check minimum length if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { return null; } - // Read packet - int length = buf.getUnsignedShort(buf.readerIndex() + 1) & 0x7fff; + int length = buf.getUnsignedShortLE(buf.readerIndex() + 1) & 0x7fff; if (buf.readableBytes() >= (length + MESSAGE_MINIMUM_LENGTH)) { - return buf.readBytes(length + MESSAGE_MINIMUM_LENGTH); + return buf.readRetainedSlice(length + MESSAGE_MINIMUM_LENGTH); } return null; diff --git a/src/org/traccar/protocol/GalileoProtocol.java b/src/org/traccar/protocol/GalileoProtocol.java index f76de04a0..93178ea52 100644 --- a/src/org/traccar/protocol/GalileoProtocol.java +++ b/src/org/traccar/protocol/GalileoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class GalileoProtocol extends BaseProtocol { @@ -35,16 +33,14 @@ public class GalileoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new GalileoFrameDecoder()); pipeline.addLast("objectEncoder", new GalileoProtocolEncoder()); pipeline.addLast("objectDecoder", new GalileoProtocolDecoder(GalileoProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/GalileoProtocolDecoder.java b/src/org/traccar/protocol/GalileoProtocolDecoder.java index d8a1651bb..7e17ebd93 100644 --- a/src/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,16 +15,17 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; @@ -92,15 +93,15 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } private void sendReply(Channel channel, int checksum) { - ChannelBuffer reply = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 3); - reply.writeByte(0x02); - reply.writeShort((short) checksum); if (channel != null) { - channel.write(reply); + ByteBuf reply = Unpooled.buffer(3); + reply.writeByte(0x02); + reply.writeShortLE((short) checksum); + channel.writeAndFlush(new NetworkMessage(reply, channel.remoteAddress())); } } - private void decodeTag(Position position, ChannelBuffer buf, int tag) { + private void decodeTag(Position position, ByteBuf buf, int tag) { switch (tag) { case 0x01: position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); @@ -109,41 +110,41 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); break; case 0x04: - position.set("deviceId", buf.readUnsignedShort()); + position.set("deviceId", buf.readUnsignedShortLE()); break; case 0x10: - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); break; case 0x20: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); break; case 0x33: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); + position.setCourse(buf.readUnsignedShortLE() * 0.1); break; case 0x34: - position.setAltitude(buf.readShort()); + position.setAltitude(buf.readShortLE()); break; case 0x40: - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); break; case 0x41: - position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE()); break; case 0x42: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE()); break; case 0x43: position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); break; case 0x44: - position.set(Position.KEY_ACCELERATION, buf.readUnsignedInt()); + position.set(Position.KEY_ACCELERATION, buf.readUnsignedIntLE()); break; case 0x45: - position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); break; case 0x46: - position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); break; case 0x50: case 0x51: @@ -153,27 +154,27 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { case 0x55: case 0x56: case 0x57: - position.set(Position.PREFIX_ADC + (tag - 0x50), buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + (tag - 0x50), buf.readUnsignedShortLE()); break; case 0x58: - position.set("rs2320", buf.readUnsignedShort()); + position.set("rs2320", buf.readUnsignedShortLE()); break; case 0x59: - position.set("rs2321", buf.readUnsignedShort()); + position.set("rs2321", buf.readUnsignedShortLE()); break; case 0xc0: - position.set("fuelTotal", buf.readUnsignedInt() * 0.5); + position.set("fuelTotal", buf.readUnsignedIntLE() * 0.5); break; case 0xc1: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte() - 40); - position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); + position.set(Position.KEY_RPM, buf.readUnsignedShortLE() * 0.125); break; case 0xc2: - position.set("canB0", buf.readUnsignedInt()); + position.set("canB0", buf.readUnsignedIntLE()); break; case 0xc3: - position.set("canB1", buf.readUnsignedInt()); + position.set("canB1", buf.readUnsignedIntLE()); break; case 0xc4: case 0xc5: @@ -197,24 +198,24 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { case 0xd8: case 0xd9: case 0xda: - position.set("can16Bit" + (tag - 0xd6), buf.readUnsignedShort()); + position.set("can16Bit" + (tag - 0xd6), buf.readUnsignedShortLE()); break; case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - position.set("can32Bit" + (tag - 0xdb), buf.readUnsignedInt()); + position.set("can32Bit" + (tag - 0xdb), buf.readUnsignedIntLE()); break; case 0xd4: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); break; case 0xe0: - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); break; case 0xe1: position.set(Position.KEY_RESULT, - buf.readBytes(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); + buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); break; case 0xe2: case 0xe3: @@ -224,10 +225,11 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { case 0xe7: case 0xe8: case 0xe9: - position.set("userData" + (tag - 0xe2), buf.readUnsignedInt()); + position.set("userData" + (tag - 0xe2), buf.readUnsignedIntLE()); break; case 0xea: - position.set("userDataArray", ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedByte()))); + position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); + position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); break; default: buf.skipBytes(getTagLength(tag)); @@ -239,10 +241,10 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header - int length = (buf.readUnsignedShort() & 0x7fff) + 3; + int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; List<Position> positions = new LinkedList<>(); Set<Integer> tags = new HashSet<>(); @@ -266,12 +268,12 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { if (tag == 0x03) { deviceSession = getDeviceSession( - channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); } else if (tag == 0x30) { hasLocation = true; position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00); - position.setLatitude(buf.readInt() / 1000000.0); - position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readIntLE() / 1000000.0); + position.setLongitude(buf.readIntLE() / 1000000.0); } else { decodeTag(position, buf, tag); } @@ -293,7 +295,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - sendReply(channel, buf.readUnsignedShort()); + sendReply(channel, buf.readUnsignedShortLE()); for (Position p : positions) { p.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/org/traccar/protocol/GalileoProtocolEncoder.java b/src/org/traccar/protocol/GalileoProtocolEncoder.java index cb6028abb..12463dc7d 100644 --- a/src/org/traccar/protocol/GalileoProtocolEncoder.java +++ b/src/org/traccar/protocol/GalileoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,39 +15,38 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; public class GalileoProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeText(String uniqueId, String text) { + private ByteBuf encodeText(String uniqueId, String text) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 256); + ByteBuf buf = Unpooled.buffer(256); buf.writeByte(0x01); - buf.writeShort(uniqueId.length() + text.length() + 11); // TODO + buf.writeShortLE(uniqueId.length() + text.length() + 11); buf.writeByte(0x03); // imei tag buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII)); buf.writeByte(0x04); // device id tag - buf.writeShort(0); // not needed if imei provided + buf.writeShortLE(0); // not needed if imei provided buf.writeByte(0xE0); // index tag - buf.writeInt(0); // index + buf.writeIntLE(0); // index buf.writeByte(0xE1); // command text tag buf.writeByte(text.length()); buf.writeBytes(text.getBytes(StandardCharsets.US_ASCII)); - buf.writeShort(Checksum.crc16(Checksum.CRC16_MODBUS, buf.toByteBuffer(0, buf.writerIndex()))); + buf.writeShortLE(Checksum.crc16(Checksum.CRC16_MODBUS, buf.nioBuffer(0, buf.writerIndex()))); return buf; } diff --git a/src/org/traccar/protocol/GatorProtocol.java b/src/org/traccar/protocol/GatorProtocol.java index 7fa4854d3..531f1238c 100644 --- a/src/org/traccar/protocol/GatorProtocol.java +++ b/src/org/traccar/protocol/GatorProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,16 +30,16 @@ public class GatorProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast("objectDecoder", new GatorProtocolDecoder(GatorProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new GatorProtocolDecoder(GatorProtocol.this)); } }); diff --git a/src/org/traccar/protocol/GatorProtocolDecoder.java b/src/org/traccar/protocol/GatorProtocolDecoder.java index 9cd746f51..f77723691 100644 --- a/src/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/org/traccar/protocol/GatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -56,9 +57,9 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { return String.format("%02d%02d%02d%02d%02d", d1, d2, d3, d4, d5); } - private void sendResponse(Channel channel, byte calibration) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, byte calibration) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(0x24); response.writeByte(0x24); // header response.writeByte(MSG_HEARTBEAT); // size response.writeShort(5); @@ -67,7 +68,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { response.writeByte(0); // slave order response.writeByte(1); // calibration response.writeByte(0x0D); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -75,7 +76,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte(); @@ -85,7 +86,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - sendResponse(channel, buf.getByte(buf.writerIndex() - 2)); + sendResponse(channel, remoteAddress, buf.getByte(buf.writerIndex() - 2)); if (type == MSG_POSITION_DATA || type == MSG_ROLLCALL_RESPONSE || type == MSG_ALARM_DATA || type == MSG_BLIND_AREA) { diff --git a/src/org/traccar/protocol/GenxProtocol.java b/src/org/traccar/protocol/GenxProtocol.java index 2b5b1a43d..2c3c4f7a0 100644 --- a/src/org/traccar/protocol/GenxProtocol.java +++ b/src/org/traccar/protocol/GenxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class GenxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GenxProtocolDecoder(GenxProtocol.this)); diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java index d4a348ce1..399a42109 100644 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; diff --git a/src/org/traccar/protocol/Gl100Protocol.java b/src/org/traccar/protocol/Gl100Protocol.java index 0fd18d44f..90beab23a 100644 --- a/src/org/traccar/protocol/Gl100Protocol.java +++ b/src/org/traccar/protocol/Gl100Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -34,18 +32,18 @@ public class Gl100Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Gl100ProtocolDecoder(Gl100Protocol.this)); diff --git a/src/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/org/traccar/protocol/Gl100ProtocolDecoder.java index 405090695..a1654d062 100644 --- a/src/org/traccar/protocol/Gl100ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl100ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; @@ -64,7 +65,7 @@ public class Gl100ProtocolDecoder extends BaseProtocolDecoder { String response = "+RESP:GTHBD,GPRS ACTIVE,"; response += sentence.substring(9, sentence.lastIndexOf(',')); response += '\0'; - channel.write(response); // heartbeat response + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); // heartbeat response } Parser parser = new Parser(PATTERN, sentence); diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index ba3baaa75..62caaf13d 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitBuffer; @@ -39,7 +39,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private Date decodeTime(ChannelBuffer buf) { + private Date decodeTime(ByteBuf buf) { DateBuilder dateBuilder = new DateBuilder() .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); @@ -50,7 +50,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_RSP_GEO = 8; public static final int MSG_RSP_COMPRESSED = 100; - private List<Position> decodeLocation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List<Position> decodeLocation(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { List<Position> positions = new LinkedList<>(); @@ -113,7 +113,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { switch (BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 8 - 2)) { case 1: - bits = new BitBuffer(buf.readBytes(3)); + bits = new BitBuffer(buf.readSlice(3)); bits.readUnsigned(2); // point attribute bits.readUnsigned(1); // fix type speed = bits.readUnsigned(12); @@ -125,7 +125,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { } break; case 2: - bits = new BitBuffer(buf.readBytes(5)); + bits = new BitBuffer(buf.readSlice(5)); bits.readUnsigned(2); // point attribute bits.readUnsigned(1); // fix type speed += bits.readSigned(7); @@ -202,7 +202,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_EVT_CRA = 23; public static final int MSG_EVT_UPC = 34; - private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -308,7 +308,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { 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) { + private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -385,9 +385,9 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + switch (buf.readSlice(4).toString(StandardCharsets.US_ASCII)) { case "+RSP": return decodeLocation(channel, remoteAddress, buf); case "+INF": diff --git a/src/org/traccar/protocol/Gl200FrameDecoder.java b/src/org/traccar/protocol/Gl200FrameDecoder.java index 960c3779a..c192cc28d 100644 --- a/src/org/traccar/protocol/Gl200FrameDecoder.java +++ b/src/org/traccar/protocol/Gl200FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,24 +15,25 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; import java.util.Set; -public class Gl200FrameDecoder extends FrameDecoder { +public class Gl200FrameDecoder extends BaseFrameDecoder { private static final int MINIMUM_LENGTH = 11; private static final Set<String> BINARY_HEADERS = new HashSet<>( Arrays.asList("+RSP", "+BSP", "+EVT", "+BVT", "+INF", "+BNF", "+HBD", "+CRD", "+BRD")); - public static boolean isBinary(ChannelBuffer buf) { + public static boolean isBinary(ByteBuf buf) { String header = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); if (header.equals("+ACK")) { return buf.getByte(buf.readerIndex() + header.length()) != (byte) ':'; @@ -43,7 +44,7 @@ public class Gl200FrameDecoder extends FrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < MINIMUM_LENGTH) { return null; @@ -73,7 +74,7 @@ public class Gl200FrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } else { @@ -83,7 +84,7 @@ public class Gl200FrameDecoder extends FrameDecoder { endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); } if (endIndex > 0) { - ChannelBuffer frame = buf.readBytes(endIndex - buf.readerIndex()); + ByteBuf frame = buf.readRetainedSlice(endIndex - buf.readerIndex()); buf.readByte(); // delimiter return frame; } diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index 799d7fe36..15ed00d06 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class Gl200Protocol extends BaseProtocol { @@ -39,18 +38,18 @@ public class Gl200Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 0de7bb926..8abaa1e37 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + import java.net.SocketAddress; public class Gl200ProtocolDecoder extends BaseProtocolDecoder { @@ -36,7 +37,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (Gl200FrameDecoder.isBinary(buf)) { return binaryProtocolDecoder.decode(channel, remoteAddress, msg); diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index ff300d429..e6187a002 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -29,6 +28,9 @@ import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.text.DateFormat; @@ -247,6 +249,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_LSW = new PatternBuilder() + .text("+RESP:").expression("GT[LT]SW,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("[01],") // type + .number("([01]),") // state + .expression(PATTERN_LOCATION.pattern()) + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN_IDA = new PatternBuilder() .text("+RESP:GTIDA,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -353,7 +370,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (type.equals("HBD")) { if (channel != null) { parser.skip(6); - channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress); + channel.writeAndFlush(new NetworkMessage( + "+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress)); } } else { Position position = new Position(getProtocolName()); @@ -389,6 +407,16 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } + private Long parseHours(String hoursString) { + if (hoursString != null) { + String[] hours = hoursString.split(":"); + return (long) (Integer.parseInt(hours[0]) * 3600 + + (hours.length > 1 ? Integer.parseInt(hours[1]) * 60 : 0) + + (hours.length > 2 ? Integer.parseInt(hours[2]) : 0)) * 1000; + } + return null; + } + private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -557,10 +585,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, Integer.parseInt(values[index++]) > 0); } if (BitUtil.check(reportMask, 2)) { - position.set("totalVehicleDistance", values[index++]); + position.set(Position.KEY_OBD_ODOMETER, values[index++]); } if (BitUtil.check(reportMask, 3)) { - position.set("totalFuelConsumption", Double.parseDouble(values[index++])); + position.set(Position.KEY_FUEL_USED, Double.parseDouble(values[index++])); } if (BitUtil.check(reportMask, 5) && !values[index++].isEmpty()) { position.set(Position.KEY_RPM, Integer.parseInt(values[index - 1])); @@ -584,7 +612,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_THROTTLE, Integer.parseInt(values[index - 1])); } if (BitUtil.check(reportMask, 11)) { - position.set(Position.KEY_HOURS, Double.parseDouble(values[index++])); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Double.parseDouble(values[index++]))); } if (BitUtil.check(reportMask, 12)) { position.set("drivingHours", Double.parseDouble(values[index++])); @@ -712,7 +740,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); } - position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.KEY_HOURS, parseHours(parser.next())); position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); @@ -766,7 +794,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, power * 0.001); } position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.KEY_HOURS, parseHours(parser.next())); position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); @@ -828,7 +856,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.KEY_IGNITION, sentence.contains("IGN")); + position.set(Position.KEY_HOURS, parseHours(parser.next())); position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); decodeDeviceTime(position, parser); @@ -836,6 +865,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeLsw(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_LSW, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.PREFIX_IN + (sentence.contains("LSW") ? 1 : 2), parser.nextInt() == 1); + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_IDA, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -918,6 +963,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, reportType == 1); } else if (type.equals("SOS")) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } else if (type.equals("DIS")) { + position.set(Position.PREFIX_IN + reportType / 10, reportType % 10 == 1); + } else if (type.equals("IGL")) { + position.set(Position.KEY_IGNITION, reportType % 10 == 0); } decodeLocation(position, parser); @@ -934,7 +983,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeDeviceTime(position, parser); if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.write("+SACK:" + parser.next() + "$", remoteAddress); + channel.writeAndFlush(new NetworkMessage("+SACK:" + parser.next() + "$", remoteAddress)); } return position; @@ -1014,7 +1063,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = ((ChannelBuffer) msg).toString(StandardCharsets.US_ASCII); + String sentence = ((ByteBuf) msg).toString(StandardCharsets.US_ASCII); int typeIndex = sentence.indexOf(":GT"); if (typeIndex < 0) { @@ -1046,6 +1095,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "IGF": result = decodeIgn(channel, remoteAddress, sentence); break; + case "LSW": + case "TSW": + result = decodeLsw(channel, remoteAddress, sentence); + break; case "IDA": result = decodeIda(channel, remoteAddress, sentence); break; diff --git a/src/org/traccar/protocol/GlobalSatProtocol.java b/src/org/traccar/protocol/GlobalSatProtocol.java index f3d07fc96..dddf07d55 100644 --- a/src/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/org/traccar/protocol/GlobalSatProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GlobalSatProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '!')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/org/traccar/protocol/GlobalSatProtocolDecoder.java index 4361e0c2f..4b67c1eff 100644 --- a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -51,7 +52,7 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder { private Position decodeOriginal(Channel channel, SocketAddress remoteAddress, String sentence) { if (channel != null) { - channel.write("ACK\r"); + channel.writeAndFlush(new NetworkMessage("ACK\r", remoteAddress)); } String format; diff --git a/src/org/traccar/protocol/GnxProtocol.java b/src/org/traccar/protocol/GnxProtocol.java index 84af24000..985f200eb 100644 --- a/src/org/traccar/protocol/GnxProtocol.java +++ b/src/org/traccar/protocol/GnxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GnxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\n\r")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java index b3a636d14..36bcba2dc 100644 --- a/src/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/org/traccar/protocol/GnxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/GoSafeProtocol.java b/src/org/traccar/protocol/GoSafeProtocol.java index bfd473df9..e4c6cc66f 100644 --- a/src/org/traccar/protocol/GoSafeProtocol.java +++ b/src/org/traccar/protocol/GoSafeProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GoSafeProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/org/traccar/protocol/GoSafeProtocolDecoder.java index 13ce839ea..f3900a61b 100644 --- a/src/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -45,75 +46,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // imei .number("(dd)(dd)(dd)") // time (hhmmss) .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("(.*)#?") // data - .compile(); - - private static final Pattern PATTERN_ITEM = new PatternBuilder() - .number("(x+)?,").optional() // event - .groupBegin() - .text("SYS:") - .expression("[^,]*,") - .groupEnd("?") - .groupBegin() - .text("GPS:") - .expression("([AV]);") // validity - .number("(d+);") // satellites - .number("([NS])(d+.d+);") // latitude - .number("([EW])(d+.d+);") // longitude - .number("(d+)?;") // speed - .number("(d+);") // course - .number("(d+);") // altitude - .number("(d+.d+)") // hdop - .number(";(d+.d+)").optional() // vdop - .expression(",?") - .groupEnd() - .groupBegin() - .text("GSM:") - .number("d*;") // registration - .number("d*;") // gsm signal - .number("(d+);") // mcc - .number("(d+);") // mnc - .number("(x+);") // lac - .number("(x+);") // cid - .number("(-d+)") // rssi - .expression("[^,]*,?") - .groupEnd("?") - .groupBegin() - .text("COT:") - .number("(d+)") // odometer - .number("(?:;d+:d+:d+)?") // engine hours - .expression(",?") - .groupEnd("?") - .groupBegin() - .text("ADC:") - .number("(d+.d+)") // power - .number("(?:;(d+.d+))?,?") // battery - .groupEnd("?") - .groupBegin() - .text("DTT:") - .number("(x+);") // status - .number("(x+)?;") // io - .number("(x+);") // geo-fence 0-119 - .number("(x+);") // geo-fence 120-155 - .number("(x+)") // event status - .number("(?:;(x+))?,?") // packet type - .groupEnd("?") - .groupBegin() - .text("ETD:").expression("([^,]+),?") - .groupEnd("?") - .groupBegin() - .text("OBD:") - .number("(x+),?") - .groupEnd("?") - .groupBegin() - .text("FUL:").expression("[^,]*,?") - .groupEnd("?") - .groupBegin() - .text("TRU:").expression("[^,]*,?") - .groupEnd("?") - .groupBegin() - .text("TAG:").expression("([^,]+),?") - .groupEnd("?") + .expression("([^#]*)#?") // data .compile(); private static final Pattern PATTERN_OLD = new PatternBuilder() @@ -133,70 +66,139 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private Position decodePosition(DeviceSession deviceSession, Parser parser, Date time) { + private void decodeFragment(Position position, String fragment) { + int dataIndex = fragment.indexOf(':'); + int index = 0; + String[] values = fragment.substring(dataIndex + 1).split(";"); + switch (fragment.substring(0, dataIndex)) { + case "GPS": + position.setValid(values[index++].equals("A")); + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + position.setLatitude(Double.parseDouble(values[index].substring(1))); + if (values[index++].charAt(0) == 'S') { + position.setLatitude(-position.getLatitude()); + } + position.setLongitude(Double.parseDouble(values[index].substring(1))); + if (values[index++].charAt(0) == 'W') { + position.setLongitude(-position.getLongitude()); + } + if (!values[index++].isEmpty()) { + position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1]))); + } + position.setCourse(Integer.parseInt(values[index++])); + position.setAltitude(Integer.parseInt(values[index++])); + if (index < values.length) { + position.set(Position.KEY_HDOP, Double.parseDouble(values[index++])); + } + if (index < values.length) { + position.set(Position.KEY_VDOP, Double.parseDouble(values[index++])); + } + break; + case "GSM": + index += 1; // registration status + index += 1; // signal strength + position.setNetwork(new Network(CellTower.from( + Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), + Integer.parseInt(values[index++], 16), Integer.parseInt(values[index++], 16), + Integer.parseInt(values[index++])))); + break; + case "COT": + if (index < values.length) { + position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); + } + if (index < values.length) { + String[] hours = values[index].split("-"); + position.set(Position.KEY_HOURS, (Integer.parseInt(hours[0]) * 3600 + + (hours.length > 1 ? Integer.parseInt(hours[1]) * 60 : 0) + + (hours.length > 2 ? Integer.parseInt(hours[2]) : 0)) * 1000); + } + break; + case "ADC": + position.set(Position.KEY_POWER, Double.parseDouble(values[index++])); + if (index < values.length) { + position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); + } + if (index < values.length) { + position.set(Position.PREFIX_ADC + 1, Double.parseDouble(values[index++])); + } + if (index < values.length) { + position.set(Position.PREFIX_ADC + 2, Double.parseDouble(values[index++])); + } + break; + case "DTT": + position.set(Position.KEY_STATUS, Integer.parseInt(values[index++], 16)); + if (!values[index++].isEmpty()) { + int io = Integer.parseInt(values[index - 1], 16); + 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, values[index++] + values[index++]); + position.set("eventStatus", values[index++]); + if (index < values.length) { + position.set("packetType", values[index++]); + } + break; + case "ETD": + position.set("eventData", values[index++]); + break; + case "OBD": + position.set("obd", values[index++]); + break; + case "TAG": + position.set("tagData", values[index++]); + break; + case "IWD": + if (index < values.length && values[index + 1].equals("0")) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index + 2]); + } + break; + default: + break; + } + } - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + private Object decodeData(DeviceSession deviceSession, Date time, String data) { - if (time != null) { - position.setTime(time); - } + List<Position> positions = new LinkedList<>(); + Position position = null; + int index = 0; + String[] fragments = data.split(","); - position.set(Position.KEY_EVENT, parser.next()); + while (index < fragments.length) { - position.setValid(parser.next().equals("A")); - position.set(Position.KEY_SATELLITES, parser.nextInt()); + if (fragments[index].isEmpty() || Character.isDigit(fragments[index].charAt(0))) { - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); + if (position != null) { + positions.add(position); + } - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - position.set(Position.KEY_VDOP, parser.nextDouble(0)); + position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(time); - if (parser.hasNext(5)) { - position.setNetwork(new Network(CellTower.from(parser.nextInt(0), parser.nextInt(0), - parser.nextHexInt(0), parser.nextHexInt(0), parser.nextInt(0)))); - } - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - } - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - - if (parser.hasNext(6)) { - 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()); - } + if (!fragments[index++].isEmpty()) { + position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index - 1])); + } - if (parser.hasNext()) { - position.set("eventData", parser.next()); - } + } else { + + decodeFragment(position, fragments[index++]); + + } - if (parser.hasNext()) { - position.set("obd", parser.next()); } - if (parser.hasNext()) { - position.set("tagData", parser.next()); + if (position != null) { + positions.add(position); } - return position; + return positions; } @Override @@ -204,7 +206,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { if (channel != null) { - channel.write("1234"); + channel.writeAndFlush(new NetworkMessage("1234", remoteAddress)); } String sentence = (String) msg; @@ -246,18 +248,12 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { } else { - Date time = null; + Date time = new Date(); if (parser.hasNext(6)) { time = parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY); } - List<Position> positions = new LinkedList<>(); - Parser itemParser = new Parser(PATTERN_ITEM, parser.next()); - while (itemParser.find()) { - positions.add(decodePosition(deviceSession, itemParser, time)); - } - - return positions; + return decodeData(deviceSession, time, parser.next()); } } diff --git a/src/org/traccar/protocol/GotopProtocol.java b/src/org/traccar/protocol/GotopProtocol.java index 5d522adf5..272c38cd0 100644 --- a/src/org/traccar/protocol/GotopProtocol.java +++ b/src/org/traccar/protocol/GotopProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GotopProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/GotopProtocolDecoder.java b/src/org/traccar/protocol/GotopProtocolDecoder.java index 29e8d87dd..728c2a8d6 100644 --- a/src/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/org/traccar/protocol/GotopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/Gps056FrameDecoder.java b/src/org/traccar/protocol/Gps056FrameDecoder.java index 4ce83dc0a..0d84bf231 100644 --- a/src/org/traccar/protocol/Gps056FrameDecoder.java +++ b/src/org/traccar/protocol/Gps056FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,26 +15,26 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; import java.nio.charset.StandardCharsets; -public class Gps056FrameDecoder extends FrameDecoder { +public class Gps056FrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_HEADER = 4; @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() >= MESSAGE_HEADER) { int length = Integer.parseInt(buf.toString(2, 2, StandardCharsets.US_ASCII)) + 5; if (buf.readableBytes() >= length) { - ChannelBuffer frame = buf.readBytes(length); - while (buf.readable() && buf.getUnsignedByte(buf.readerIndex()) != '$') { + ByteBuf frame = buf.readRetainedSlice(length); + while (buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) != '$') { buf.readByte(); } return frame; diff --git a/src/org/traccar/protocol/Gps056Protocol.java b/src/org/traccar/protocol/Gps056Protocol.java index 33c190ad2..f5122830d 100644 --- a/src/org/traccar/protocol/Gps056Protocol.java +++ b/src/org/traccar/protocol/Gps056Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class Gps056Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Gps056FrameDecoder()); pipeline.addLast("objectDecoder", new Gps056ProtocolDecoder(Gps056Protocol.this)); } diff --git a/src/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/org/traccar/protocol/Gps056ProtocolDecoder.java index ccb389250..13027142f 100644 --- a/src/org/traccar/protocol/Gps056ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps056ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -33,20 +34,20 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static void sendResponse(Channel channel, String type, String imei, ChannelBuffer content) { + private static void sendResponse(Channel channel, String type, String imei, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); String header = "*" + type + imei; response.writeBytes(header.getBytes(StandardCharsets.US_ASCII)); if (content != null) { response.writeBytes(content); } response.writeByte('#'); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } - private static double decodeCoordinate(ChannelBuffer buf) { + private static double decodeCoordinate(ByteBuf buf) { double degrees = buf.getUnsignedShort(buf.readerIndex()) / 100; double minutes = buf.readUnsignedShort() % 100 + buf.readUnsignedShort() * 0.0001; degrees += minutes / 60; @@ -57,12 +58,12 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder { return degrees; } - private static void decodeStatus(ChannelBuffer buf, Position position) { + private static void decodeStatus(ByteBuf buf, Position position) { position.set(Position.KEY_INPUT, buf.readUnsignedByte()); position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - position.set(Position.PREFIX_ADC + 1, ChannelBuffers.swapShort(buf.readShort()) * 5.06); // mV + position.set(Position.PREFIX_ADC + 1, buf.readShortLE() * 5.06); // mV position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); @@ -73,13 +74,13 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.skipBytes(2); // length - String type = buf.readBytes(7).toString(StandardCharsets.US_ASCII); - String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII); + String type = buf.readSlice(7).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { @@ -88,8 +89,12 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder { if (type.startsWith("LOGN")) { - sendResponse(channel, "LGSA" + type.substring(4), imei, - ChannelBuffers.copiedBuffer("1", StandardCharsets.US_ASCII)); + ByteBuf content = Unpooled.copiedBuffer("1", StandardCharsets.US_ASCII); + try { + sendResponse(channel, "LGSA" + type.substring(4), imei, content); + } finally { + content.release(); + } } else if (type.startsWith("GPSL")) { @@ -109,7 +114,7 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder { decodeStatus(buf, position); - sendResponse(channel, "GPSA" + type.substring(4), imei, buf.readBytes(2)); + sendResponse(channel, "GPSA" + type.substring(4), imei, buf.readSlice(2)); return position; diff --git a/src/org/traccar/protocol/Gps103Protocol.java b/src/org/traccar/protocol/Gps103Protocol.java index a5bd32261..068f362c9 100644 --- a/src/org/traccar/protocol/Gps103Protocol.java +++ b/src/org/traccar/protocol/Gps103Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -45,9 +43,9 @@ public class Gps103Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(2048, "\r\n", "\n", ";")); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); @@ -55,9 +53,9 @@ public class Gps103Protocol extends BaseProtocol { pipeline.addLast("objectDecoder", new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gps103ProtocolEncoder()); diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index 85b4dcada..2b797d05a 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,17 +15,20 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class Gps103ProtocolDecoder extends BaseProtocolDecoder { @@ -38,10 +41,19 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .text("imei:") .number("(d+),") // imei .expression("([^,]+),") // alarm + .groupBegin() .number("(dd)/?(dd)/?(dd) ?") // local date (yymmdd) .number("(dd):?(dd)(?:dd)?,") // local time (hhmmss) + .or() + .number("d*,") + .groupEnd() .expression("([^,]+)?,") // rfid - .expression("[FL],") // full / low + .groupBegin() + .text("L,,,") + .number("(x+),,") // lac + .number("(x+),,,") // cid + .or() + .text("F,") .groupBegin() .number("(dd)(dd)(dd).d+") // time utc (hhmmss) .or() @@ -55,32 +67,18 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .expression("([EW]),").optional() .number("(d+)(dd.d+),") // longitude (dddmm.mmmm) .expression("([EW])?,").optional() - .number("(d+.?d*)?,?") // speed - .number("(d+.?d*)?,?") // course - .number("(d+.?d*)?,?") // altitude - .expression("([^,;]+)?,?") - .expression("([^,;]+)?,?") - .expression("([^,;]+)?,?") - .expression("([^,;]+)?,?") - .expression("([^,;]+)?,?") - .any() - .compile(); - - private static final Pattern PATTERN_NETWORK = new PatternBuilder() - .text("imei:") - .number("(d+),") // imei - .expression("[^,]+,") // alarm - .number("d*,,") - .text("L,,,") - .number("(x+),,") // lac - .number("(x+),,,") // cid + .number("(d+.?d*)?").optional() // speed + .number(",(d+.?d*)?").optional() // course + .number(",(d+.?d*)?").optional() // altitude + .number(",([01])?").optional() // ignition + .number(",([01])?").optional() // door + .number(",(?:(d+.d+)%)?").optional() // fuel 1 + .number(",(?:(d+.d+)%)?").optional() // fuel 2 + .number("(-?d+)?") // temperature + .groupEnd() .any() .compile(); - private static final Pattern PATTERN_HANDSHAKE = new PatternBuilder() - .number("##,imei:(d+),A") - .compile(); - private static final Pattern PATTERN_OBD = new PatternBuilder() .text("imei:") .number("(d+),") // imei @@ -105,7 +103,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { if (value.startsWith("T:")) { return Position.ALARM_TEMPERATURE; } else if (value.startsWith("oil")) { - return Position.ALARM_OIL_LEAK; + return Position.ALARM_FUEL_LEAK; } switch (value) { case "tracker": @@ -143,85 +141,9 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - // Send response #1 - if (sentence.contains("##")) { - if (channel != null) { - channel.write("LOAD", remoteAddress); - Parser handshakeParser = new Parser(PATTERN_HANDSHAKE, sentence); - if (handshakeParser.matches()) { - getDeviceSession(channel, remoteAddress, handshakeParser.next()); - } - } - return null; - } - - // Send response #2 - if (!sentence.isEmpty() && Character.isDigit(sentence.charAt(0))) { - if (channel != null) { - channel.write("ON", remoteAddress); - } - int start = sentence.indexOf("imei:"); - if (start >= 0) { - sentence = sentence.substring(start); - } else { - return null; - } - } - - Position position = new Position(getProtocolName()); - - Parser parser = new Parser(PATTERN_NETWORK, sentence); - if (parser.matches()) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.setNetwork(new Network( - CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); - - return position; - - } - - parser = new Parser(PATTERN_OBD, sentence); - if (parser.matches()) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, parser.nextDateTime()); - - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - parser.nextDouble(0); // instant fuel consumption - position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble(0)); - position.set(Position.KEY_HOURS, parser.nextInt()); - position.set(Position.KEY_OBD_SPEED, parser.nextInt(0)); - position.set(Position.KEY_ENGINE_LOAD, parser.next()); - position.set(Position.KEY_COOLANT_TEMP, parser.nextInt()); - position.set(Position.KEY_THROTTLE, parser.next()); - position.set(Position.KEY_RPM, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_DTCS, parser.next().replace(',', ' ').trim()); - - return position; - - } + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, String sentence) { - parser = new Parser(PATTERN, sentence); + Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } @@ -231,13 +153,15 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); String alarm = parser.next(); position.set(Position.KEY_ALARM, decodeAlarm(alarm)); if (alarm.equals("help me")) { if (channel != null) { - channel.write("**,imei:" + imei + ",E;", remoteAddress); + channel.writeAndFlush(new NetworkMessage("**,imei:" + imei + ",E;", remoteAddress)); } } else if (alarm.equals("acc on")) { position.set(Position.KEY_IGNITION, true); @@ -246,7 +170,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } else if (alarm.startsWith("T:")) { position.set(Position.PREFIX_TEMP + 1, alarm.substring(2)); } else if (alarm.startsWith("oil ")) { - position.set("oil", alarm.substring(4)); + position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(alarm.substring(4))); } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { position.set(Position.KEY_EVENT, alarm); } @@ -262,36 +186,123 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); } - String utcHours = parser.next(); - String utcMinutes = parser.next(); + if (parser.hasNext(2)) { - dateBuilder.setTime(localHours, localMinutes, parser.nextInt(0)); + getLastLocation(position, null); - // Timezone calculation - if (utcHours != null && utcMinutes != null) { - int deltaMinutes = (localHours - Integer.parseInt(utcHours)) * 60; - deltaMinutes += localMinutes - Integer.parseInt(utcMinutes); - if (deltaMinutes <= -12 * 60) { - deltaMinutes += 24 * 60; - } else if (deltaMinutes > 12 * 60) { - deltaMinutes -= 24 * 60; + position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + + } else { + + String utcHours = parser.next(); + String utcMinutes = parser.next(); + + dateBuilder.setTime(localHours, localMinutes, parser.nextInt(0)); + + // Timezone calculation + if (utcHours != null && utcMinutes != null) { + int deltaMinutes = (localHours - Integer.parseInt(utcHours)) * 60; + deltaMinutes += localMinutes - Integer.parseInt(utcMinutes); + if (deltaMinutes <= -12 * 60) { + deltaMinutes += 24 * 60; + } else if (deltaMinutes > 12 * 60) { + deltaMinutes -= 24 * 60; + } + dateBuilder.addMinute(-deltaMinutes); + } + position.setTime(dateBuilder.getDate()); + + position.setValid(parser.next().equals("A")); + position.setFixTime(position.getDeviceTime()); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM)); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + if (parser.hasNext()) { + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + } + if (parser.hasNext()) { + position.set(Position.KEY_DOOR, parser.nextInt() == 1); } - dateBuilder.addMinute(-deltaMinutes); + position.set("fuel1", parser.nextDouble()); + position.set("fuel2", parser.nextDouble()); + position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + + } + + return position; + } + + private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_OBD, sentence); + if (!parser.matches()) { + return null; } - position.setTime(dateBuilder.getDate()); - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, parser.nextDateTime()); - for (int i = 1; i <= 5; i++) { - position.set(Position.PREFIX_IO + i, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextInt(0)); + parser.nextDouble(0); // instant fuel consumption + position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble(0)); + if (parser.hasNext()) { + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(parser.nextInt())); } + position.set(Position.KEY_OBD_SPEED, parser.nextInt(0)); + position.set(Position.KEY_ENGINE_LOAD, parser.next()); + position.set(Position.KEY_COOLANT_TEMP, parser.nextInt()); + position.set(Position.KEY_THROTTLE, parser.next()); + position.set(Position.KEY_RPM, parser.nextInt(0)); + position.set(Position.KEY_BATTERY, parser.nextDouble(0)); + position.set(Position.KEY_DTCS, parser.next().replace(',', ' ').trim()); return position; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + if (sentence.contains("##")) { + if (channel != null) { + channel.writeAndFlush(new NetworkMessage("LOAD", remoteAddress)); + Matcher matcher = Pattern.compile("##,imei:(\\d+),A").matcher(sentence); + if (matcher.matches()) { + getDeviceSession(channel, remoteAddress, matcher.group(1)); + } + } + return null; + } + + if (!sentence.isEmpty() && Character.isDigit(sentence.charAt(0))) { + if (channel != null) { + channel.writeAndFlush(new NetworkMessage("ON", remoteAddress)); + } + int start = sentence.indexOf("imei:"); + if (start >= 0) { + sentence = sentence.substring(start); + } else { + return null; + } + } + + if (sentence.contains("OBD")) { + return decodeObd(channel, remoteAddress, sentence); + } else { + return decodeRegular(channel, remoteAddress, sentence); + } + } + } diff --git a/src/org/traccar/protocol/GpsGateProtocol.java b/src/org/traccar/protocol/GpsGateProtocol.java index c7dc2c4f3..4685e40b7 100644 --- a/src/org/traccar/protocol/GpsGateProtocol.java +++ b/src/org/traccar/protocol/GpsGateProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GpsGateProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/org/traccar/protocol/GpsGateProtocolDecoder.java index 5c7096276..6eff3eb76 100644 --- a/src/org/traccar/protocol/GpsGateProtocolDecoder.java +++ b/src/org/traccar/protocol/GpsGateProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -65,9 +66,9 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private void send(Channel channel, String message) { + private void send(Channel channel, SocketAddress remoteAddress, String message) { if (channel != null) { - channel.write(message + Checksum.nmea(message) + "\r\n"); + channel.writeAndFlush(new NetworkMessage(message + Checksum.nmea(message) + "\r\n", remoteAddress)); } } @@ -79,7 +80,6 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { if (sentence.startsWith("$FRLIN,")) { - // Login int beginIndex = sentence.indexOf(',', 7); if (beginIndex != -1) { beginIndex += 1; @@ -89,22 +89,21 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null) { if (channel != null) { - send(channel, "$FRSES," + channel.getId()); + send(channel, remoteAddress, "$FRSES," + channel.id().asShortText()); } } else { - send(channel, "$FRERR,AuthError,Unknown device"); + send(channel, remoteAddress, "$FRERR,AuthError,Unknown device"); } } else { - send(channel, "$FRERR,AuthError,Parse error"); + send(channel, remoteAddress, "$FRERR,AuthError,Parse error"); } } else { - send(channel, "$FRERR,AuthError,Parse error"); + send(channel, remoteAddress, "$FRERR,AuthError,Parse error"); } } else if (sentence.startsWith("$FRVER,")) { - // Version check - send(channel, "$FRVER,1,0,GpsGate Server 1.0"); + send(channel, remoteAddress, "$FRVER,1,0,GpsGate Server 1.0"); } else if (sentence.startsWith("$GPRMC,")) { diff --git a/src/org/traccar/protocol/GpsMarkerProtocol.java b/src/org/traccar/protocol/GpsMarkerProtocol.java index 5c64d16b2..0655d2c88 100644 --- a/src/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/org/traccar/protocol/GpsMarkerProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class GpsMarkerProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java index ca5bdcbed..a6e39e353 100644 --- a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java +++ b/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/GpsmtaProtocol.java b/src/org/traccar/protocol/GpsmtaProtocol.java index 2d1181bec..b2720cb8a 100644 --- a/src/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/org/traccar/protocol/GpsmtaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class GpsmtaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); diff --git a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/org/traccar/protocol/GpsmtaProtocolDecoder.java index c71162078..1d80178cb 100644 --- a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java +++ b/src/org/traccar/protocol/GpsmtaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; @@ -81,7 +82,7 @@ public class GpsmtaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); if (channel != null) { - channel.write(time, remoteAddress); + channel.writeAndFlush(new NetworkMessage(time, remoteAddress)); } return position; diff --git a/src/org/traccar/protocol/GranitFrameDecoder.java b/src/org/traccar/protocol/GranitFrameDecoder.java index 7e8f4a3f5..bb7f4be44 100644 --- a/src/org/traccar/protocol/GranitFrameDecoder.java +++ b/src/org/traccar/protocol/GranitFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,29 +15,29 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BufferUtil; -public class GranitFrameDecoder extends FrameDecoder { +public class GranitFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - int indexEnd = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("\r\n")); + int indexEnd = BufferUtil.indexOf("\r\n", buf); if (indexEnd != -1) { - int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("~")); + int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '~'); if (indexTilde != -1 && indexTilde < indexEnd) { - int length = buf.getUnsignedShort(indexTilde + 1); - indexEnd = buf.indexOf(indexTilde + 2 + length, buf.writerIndex(), new StringFinder("\r\n")); + int length = buf.getUnsignedShortLE(indexTilde + 1); + indexEnd = BufferUtil.indexOf("\r\n", buf, indexTilde + 2 + length, buf.writerIndex()); if (indexEnd == -1) { return null; } } - ChannelBuffer frame = buf.readBytes(indexEnd - buf.readerIndex()); + ByteBuf frame = buf.readRetainedSlice(indexEnd - buf.readerIndex()); buf.skipBytes(2); return frame; } diff --git a/src/org/traccar/protocol/GranitProtocol.java b/src/org/traccar/protocol/GranitProtocol.java index 32e8e00b0..5855d34ee 100644 --- a/src/org/traccar/protocol/GranitProtocol.java +++ b/src/org/traccar/protocol/GranitProtocol.java @@ -1,6 +1,6 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class GranitProtocol extends BaseProtocol { @@ -41,16 +39,14 @@ public class GranitProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new GranitFrameDecoder()); pipeline.addLast("objectEncoder", new GranitProtocolEncoder()); pipeline.addLast("objectDecoder", new GranitProtocolDecoder(GranitProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/GranitProtocolDecoder.java b/src/org/traccar/protocol/GranitProtocolDecoder.java index 50d879bb4..d4aa7e6e8 100644 --- a/src/org/traccar/protocol/GranitProtocolDecoder.java +++ b/src/org/traccar/protocol/GranitProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,19 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; -import org.traccar.helper.StringFinder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; @@ -50,35 +49,35 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { adc4Ratio = Context.getConfig().getDouble("granit.adc4Ratio", 1); } - public static void appendChecksum(ChannelBuffer buffer, int length) { + public static void appendChecksum(ByteBuf buffer, int length) { buffer.writeByte('*'); - int checksum = Checksum.xor(buffer.toByteBuffer(0, length)) & 0xFF; + int checksum = Checksum.xor(buffer.nioBuffer(0, length)) & 0xFF; String checksumString = String.format("%02X", checksum); buffer.writeBytes(checksumString.getBytes(StandardCharsets.US_ASCII)); buffer.writeByte('\r'); buffer.writeByte('\n'); } private static void sendResponseCurrent(Channel channel, int deviceId, long time) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(); response.writeBytes("BB+UGRC~".getBytes(StandardCharsets.US_ASCII)); - response.writeShort(6); // length + response.writeShortLE(6); // length response.writeInt((int) time); - response.writeShort(deviceId); + response.writeShortLE(deviceId); appendChecksum(response, 16); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } private static void sendResponseArchive(Channel channel, int deviceId, int packNum) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(); response.writeBytes("BB+ARCF~".getBytes(StandardCharsets.US_ASCII)); - response.writeShort(4); // length - response.writeShort(packNum); - response.writeShort(deviceId); + response.writeShortLE(4); // length + response.writeShortLE(packNum); + response.writeShortLE(deviceId); appendChecksum(response, 14); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } - private void decodeStructure(ChannelBuffer buf, Position position) { + private void decodeStructure(ByteBuf buf, Position position) { short flags = buf.readUnsignedByte(); position.setValid(BitUtil.check(flags, 7)); if (BitUtil.check(flags, 1)) { @@ -93,8 +92,8 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { int lonDegrees = buf.readUnsignedByte(); int latDegrees = buf.readUnsignedByte(); - int lonMinutes = buf.readUnsignedShort(); - int latMinutes = buf.readUnsignedShort(); + int lonMinutes = buf.readUnsignedShortLE(); + int latMinutes = buf.readUnsignedShortLE(); double latitude = latDegrees + latMinutes / 60000.0; double longitude = lonDegrees + lonMinutes / 60000.0; @@ -119,7 +118,7 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { } position.setCourse(course); - position.set(Position.KEY_DISTANCE, buf.readShort()); + position.set(Position.KEY_DISTANCE, buf.readShortLE()); int analogIn1 = buf.readUnsignedByte(); int analogIn2 = buf.readUnsignedByte(); @@ -150,9 +149,9 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("~")); + int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '~'); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); @@ -171,17 +170,17 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { if (buf.readableBytes() < HEADER_LENGTH) { return null; } - String header = buf.readBytes(HEADER_LENGTH).toString(StandardCharsets.US_ASCII); + String header = buf.readSlice(HEADER_LENGTH).toString(StandardCharsets.US_ASCII); if (header.equals("+RRCB~")) { - buf.skipBytes(2); //binary length 26 - int deviceId = buf.readUnsignedShort(); + buf.skipBytes(2); // binary length 26 + int deviceId = buf.readUnsignedShortLE(); deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); if (deviceSession == null) { return null; } - long unixTime = buf.readUnsignedInt(); + long unixTime = buf.readUnsignedIntLE(); if (channel != null) { sendResponseCurrent(channel, deviceId, unixTime); } @@ -195,8 +194,8 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { } else if (header.equals("+DDAT~")) { - buf.skipBytes(2); //binary length - int deviceId = buf.readUnsignedShort(); + buf.skipBytes(2); // binary length + int deviceId = buf.readUnsignedShortLE(); deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); if (deviceSession == null) { return null; @@ -206,15 +205,15 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder { return null; } byte nblocks = buf.readByte(); - int packNum = buf.readUnsignedShort(); + int packNum = buf.readUnsignedShortLE(); if (channel != null) { sendResponseArchive(channel, deviceId, packNum); } List<Position> positions = new ArrayList<>(); while (nblocks > 0) { nblocks--; - long unixTime = buf.readUnsignedInt(); - int timeIncrement = buf.getUnsignedShort(buf.readerIndex() + 120); + long unixTime = buf.readUnsignedIntLE(); + int timeIncrement = buf.getUnsignedShortLE(buf.readerIndex() + 120); for (int i = 0; i < 6; i++) { if (buf.getUnsignedByte(buf.readerIndex()) != 0xFE) { Position position = new Position(getProtocolName()); diff --git a/src/org/traccar/protocol/GranitProtocolEncoder.java b/src/org/traccar/protocol/GranitProtocolEncoder.java index dbfd30ff1..bde267ee6 100644 --- a/src/org/traccar/protocol/GranitProtocolEncoder.java +++ b/src/org/traccar/protocol/GranitProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.traccar.protocol; +package org.traccar.protocol; import java.nio.charset.StandardCharsets; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -44,7 +44,7 @@ public class GranitProtocolEncoder extends BaseProtocolEncoder { return null; } if (!commandString.isEmpty()) { - ChannelBuffer commandBuf = ChannelBuffers.dynamicBuffer(); + ByteBuf commandBuf = Unpooled.buffer(); commandBuf.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); GranitProtocolDecoder.appendChecksum(commandBuf, commandString.length()); return commandBuf; diff --git a/src/org/traccar/protocol/Gt02Protocol.java b/src/org/traccar/protocol/Gt02Protocol.java index e484b66cd..f44cb3979 100644 --- a/src/org/traccar/protocol/Gt02Protocol.java +++ b/src/org/traccar/protocol/Gt02Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class Gt02Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); pipeline.addLast("objectDecoder", new Gt02ProtocolDecoder(Gt02Protocol.this)); } diff --git a/src/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/org/traccar/protocol/Gt02ProtocolDecoder.java index a4f1a4161..ab4c7022e 100644 --- a/src/org/traccar/protocol/Gt02ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt02ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -42,7 +44,7 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readByte(); // size @@ -53,7 +55,7 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder { int power = buf.readUnsignedByte(); int gsm = buf.readUnsignedByte(); - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; @@ -73,7 +75,7 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { byte[] response = {0x54, 0x68, 0x1A, 0x0D, 0x0A}; - channel.write(ChannelBuffers.wrappedBuffer(response)); + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); } } else if (type == MSG_DATA) { @@ -108,7 +110,7 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); position.set(Position.KEY_RESULT, - buf.readBytes(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); + buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); } else { diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index c8b5e56ae..cc934be42 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,16 +15,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class Gt06FrameDecoder extends FrameDecoder { +public class Gt06FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 5) { return null; @@ -39,14 +39,14 @@ public class Gt06FrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } int endIndex = buf.readerIndex() - 1; do { endIndex = buf.indexOf(endIndex + 1, buf.writerIndex(), (byte) 0x0d); if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { - return buf.readBytes(endIndex + 2 - buf.readerIndex()); + return buf.readRetainedSlice(endIndex + 2 - buf.readerIndex()); } } while (endIndex > 0); diff --git a/src/org/traccar/protocol/Gt06Protocol.java b/src/org/traccar/protocol/Gt06Protocol.java index f45ac95ee..e00a585ca 100644 --- a/src/org/traccar/protocol/Gt06Protocol.java +++ b/src/org/traccar/protocol/Gt06Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -35,9 +34,9 @@ public class Gt06Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Gt06FrameDecoder()); pipeline.addLast("objectEncoder", new Gt06ProtocolEncoder()); pipeline.addLast("objectDecoder", new Gt06ProtocolDecoder(Gt06Protocol.this)); diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 3e5ebc8c5..dfb0b5e07 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -15,12 +15,14 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; @@ -44,7 +46,7 @@ import java.util.regex.Pattern; public class Gt06ProtocolDecoder extends BaseProtocolDecoder { - private final Map<Integer, ChannelBuffer> photos = new HashMap<>(); + private final Map<Integer, ByteBuf> photos = new HashMap<>(); public Gt06ProtocolDecoder(Gt06Protocol protocol) { super(protocol); @@ -162,9 +164,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - private void sendResponse(Channel channel, boolean extended, int type, int index, ChannelBuffer content) { + private void sendResponse(Channel channel, boolean extended, int type, int index, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); int length = 5 + (content != null ? content.readableBytes() : 0); if (extended) { response.writeShort(0x7979); @@ -176,25 +178,26 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { response.writeByte(type); if (content != null) { response.writeBytes(content); + content.release(); } response.writeShort(index); response.writeShort(Checksum.crc16(Checksum.CRC16_X25, - response.toByteBuffer(2, response.writerIndex() - 2))); + response.nioBuffer(2, response.writerIndex() - 2))); response.writeByte('\r'); response.writeByte('\n'); // ending - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } private void sendPhotoRequest(Channel channel, int pictureId) { - ChannelBuffer photo = photos.get(pictureId); - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf photo = photos.get(pictureId); + ByteBuf content = Unpooled.buffer(); content.writeInt(pictureId); content.writeInt(photo.writerIndex()); content.writeShort(Math.min(photo.writableBytes(), 1024)); sendResponse(channel, false, MSG_X1_PHOTO_DATA, 0, content); } - private boolean decodeGps(Position position, ChannelBuffer buf, boolean hasLength, TimeZone timezone) { + private boolean decodeGps(Position position, ByteBuf buf, boolean hasLength, TimeZone timezone) { DateBuilder dateBuilder = new DateBuilder(timezone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -232,7 +235,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) { + private boolean decodeLbs(Position position, ByteBuf buf, boolean hasLength) { int length = 0; if (hasLength) { @@ -255,7 +258,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeStatus(Position position, ChannelBuffer buf) { + private boolean decodeStatus(Position position, ByteBuf buf) { int status = buf.readUnsignedByte(); @@ -367,7 +370,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { int length = buf.readUnsignedByte(); int dataLength = length - 5; @@ -386,7 +389,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_LOGIN) { - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); buf.readUnsignedShort(); // type deviceSession = getDeviceSession(channel, remoteAddress, imei); @@ -428,6 +431,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(status, 1)); position.set(Position.KEY_CHARGE, BitUtil.check(status, 2)); + if (buf.readableBytes() >= 2 + 6) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + } + if (buf.readableBytes() >= 1 + 6) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + } + sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); return position; @@ -435,7 +445,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_ADDRESS_REQUEST) { String response = "NA&&NA&&0##"; - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); content.writeByte(response.length()); content.writeInt(0); content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); @@ -444,7 +454,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_TIME_REQUEST) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); content.writeByte(calendar.get(Calendar.YEAR) - 2000); content.writeByte(calendar.get(Calendar.MONTH) + 1); content.writeByte(calendar.get(Calendar.DAY_OF_MONTH)); @@ -482,7 +492,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // photo source buf.readUnsignedByte(); // picture format - ChannelBuffer photo = ChannelBuffers.buffer(buf.readInt()); + ByteBuf photo = Unpooled.buffer(buf.readInt()); int pictureId = buf.readInt(); photos.put(pictureId, photo); sendPhotoRequest(channel, pictureId); @@ -500,7 +510,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeWifi(ChannelBuffer buf, DeviceSession deviceSession) throws Exception { + private Object decodeWifi(ByteBuf buf, DeviceSession deviceSession) throws Exception { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -537,7 +547,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBasicOther(Channel channel, ChannelBuffer buf, + private Object decodeBasicOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type, int dataLength) throws Exception { Position position = new Position(getProtocolName()); @@ -571,7 +581,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { 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:"); + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } @@ -588,7 +598,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (commandLength > 0) { buf.readUnsignedByte(); // server flag (reserved) position.set(Position.KEY_RESULT, - buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); + buf.readSlice(commandLength - 1).toString(StandardCharsets.US_ASCII)); } } else if (isSupported(type)) { @@ -619,7 +629,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else { - buf.skipBytes(dataLength); + if (dataLength > 0) { + buf.skipBytes(dataLength); + } if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); } @@ -640,7 +652,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -662,9 +674,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // server flag String data; if (buf.readUnsignedByte() == 1) { - data = buf.readBytes(buf.readableBytes() - 6).toString(StandardCharsets.US_ASCII); + data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.US_ASCII); } else { - data = buf.readBytes(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); + data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); } if (decodeLocationString(position, data) == null) { @@ -704,7 +716,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int pictureId = buf.readInt(); - ChannelBuffer photo = photos.get(pictureId); + ByteBuf photo = photos.get(pictureId); buf.readUnsignedInt(); // offset buf.readBytes(photo, buf.readUnsignedShort()); @@ -715,7 +727,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); position.set( Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); - photos.remove(pictureId); + photos.remove(pictureId).release(); } } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { @@ -772,7 +784,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; int header = buf.readShort(); diff --git a/src/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/org/traccar/protocol/Gt06ProtocolEncoder.java index daf045f4f..46b4fa5a4 100644 --- a/src/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.Checksum; @@ -27,11 +27,11 @@ import java.nio.charset.StandardCharsets; public class Gt06ProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(long deviceId, String content) { + private ByteBuf encodeContent(long deviceId, String content) { boolean language = Context.getIdentityManager().lookupAttributeBoolean(deviceId, "gt06.language", false, true); - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x78); buf.writeByte(0x78); @@ -50,7 +50,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(0); // message index - buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.toByteBuffer(2, buf.writerIndex() - 2))); + buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.nioBuffer(2, buf.writerIndex() - 2))); buf.writeByte('\r'); buf.writeByte('\n'); diff --git a/src/org/traccar/protocol/Gt30Protocol.java b/src/org/traccar/protocol/Gt30Protocol.java index 186002a35..43bb5a70b 100644 --- a/src/org/traccar/protocol/Gt30Protocol.java +++ b/src/org/traccar/protocol/Gt30Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Gt30Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/org/traccar/protocol/Gt30ProtocolDecoder.java index 27081a108..ac1557994 100644 --- a/src/org/traccar/protocol/Gt30ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt30ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/H02FrameDecoder.java b/src/org/traccar/protocol/H02FrameDecoder.java index 391fccc87..583ad599f 100644 --- a/src/org/traccar/protocol/H02FrameDecoder.java +++ b/src/org/traccar/protocol/H02FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,12 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class H02FrameDecoder extends FrameDecoder { +public class H02FrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_SHORT = 32; private static final int MESSAGE_LONG = 45; @@ -33,7 +33,7 @@ public class H02FrameDecoder extends FrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { char marker = (char) buf.getByte(buf.readerIndex()); @@ -50,8 +50,8 @@ public class H02FrameDecoder extends FrameDecoder { // Return text message int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); if (index != -1) { - ChannelBuffer result = buf.readBytes(index + 1 - buf.readerIndex()); - while (buf.readable() + ByteBuf result = buf.readRetainedSlice(index + 1 - buf.readerIndex()); + while (buf.isReadable() && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) { buf.readByte(); // skip new line } @@ -71,7 +71,7 @@ public class H02FrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= messageLength) { - return buf.readBytes(messageLength); + return buf.readRetainedSlice(messageLength); } break; @@ -79,7 +79,7 @@ public class H02FrameDecoder extends FrameDecoder { case 'X': if (buf.readableBytes() >= MESSAGE_SHORT) { - return buf.readBytes(MESSAGE_SHORT); + return buf.readRetainedSlice(MESSAGE_SHORT); } break; diff --git a/src/org/traccar/protocol/H02Protocol.java b/src/org/traccar/protocol/H02Protocol.java index 66965e9db..29ac89f78 100644 --- a/src/org/traccar/protocol/H02Protocol.java +++ b/src/org/traccar/protocol/H02Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.Context; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -41,9 +39,9 @@ public class H02Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { int messageLength = Context.getConfig().getInteger(getName() + ".messageLength"); pipeline.addLast("frameDecoder", new H02FrameDecoder(messageLength)); pipeline.addLast("stringEncoder", new StringEncoder()); @@ -51,9 +49,9 @@ public class H02Protocol extends BaseProtocol { pipeline.addLast("objectDecoder", new H02ProtocolDecoder(H02Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new H02ProtocolEncoder()); pipeline.addLast("objectDecoder", new H02ProtocolDecoder(H02Protocol.this)); diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index 9764adf04..2abde7d6f 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; @@ -40,7 +40,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static double readCoordinate(ChannelBuffer buf, boolean lon) { + private static double readCoordinate(ByteBuf buf, boolean lon) { int degrees = BcdUtil.readInteger(buf, 2); if (lon) { @@ -99,14 +99,14 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + private Position decodeBinary(ByteBuf buf, Channel channel, SocketAddress remoteAddress) { Position position = new Position(getProtocolName()); buf.readByte(); // marker DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(5))); + channel, remoteAddress, ByteBufUtil.hexDump(buf.readSlice(5))); if (deviceSession == null) { return null; } @@ -148,7 +148,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .text("*") .expression("..,") // manufacturer - .number("(d+),") // imei + .number("(d+)?,") // imei .groupBegin() .text("VP1,") .or() @@ -451,7 +451,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; String marker = buf.toString(0, 1, StandardCharsets.US_ASCII); switch (marker) { diff --git a/src/org/traccar/protocol/H02ProtocolEncoder.java b/src/org/traccar/protocol/H02ProtocolEncoder.java index 7b5ff13bb..fb418dbab 100644 --- a/src/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/org/traccar/protocol/H02ProtocolEncoder.java @@ -1,6 +1,6 @@ /* * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) - * 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. diff --git a/src/org/traccar/protocol/HaicomProtocol.java b/src/org/traccar/protocol/HaicomProtocol.java index 4380dd2cc..45bf9f890 100644 --- a/src/org/traccar/protocol/HaicomProtocol.java +++ b/src/org/traccar/protocol/HaicomProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class HaicomProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '*')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/HaicomProtocolDecoder.java b/src/org/traccar/protocol/HaicomProtocolDecoder.java index 94ec93cfb..b828b5a16 100644 --- a/src/org/traccar/protocol/HaicomProtocolDecoder.java +++ b/src/org/traccar/protocol/HaicomProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/HomtecsProtocol.java b/src/org/traccar/protocol/HomtecsProtocol.java index a9ea19c51..e57cb96be 100644 --- a/src/org/traccar/protocol/HomtecsProtocol.java +++ b/src/org/traccar/protocol/HomtecsProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class HomtecsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder 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/HomtecsProtocolDecoder.java b/src/org/traccar/protocol/HomtecsProtocolDecoder.java index f4ae54d1f..80294795e 100644 --- a/src/org/traccar/protocol/HomtecsProtocolDecoder.java +++ b/src/org/traccar/protocol/HomtecsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/HuaShengFrameDecoder.java b/src/org/traccar/protocol/HuaShengFrameDecoder.java index 4c29b7915..bd52aa9e7 100644 --- a/src/org/traccar/protocol/HuaShengFrameDecoder.java +++ b/src/org/traccar/protocol/HuaShengFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,19 +15,17 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class HuaShengFrameDecoder extends FrameDecoder { +public class HuaShengFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 2) { return null; @@ -35,7 +33,7 @@ public class HuaShengFrameDecoder extends FrameDecoder { int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0xC0); if (index != -1) { - ChannelBuffer result = ChannelBuffers.buffer(index + 1 - buf.readerIndex()); + ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); while (buf.readerIndex() <= index) { int b = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/HuaShengProtocol.java b/src/org/traccar/protocol/HuaShengProtocol.java index e0fddae20..b1f187e14 100644 --- a/src/org/traccar/protocol/HuaShengProtocol.java +++ b/src/org/traccar/protocol/HuaShengProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class HuaShengProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new HuaShengFrameDecoder()); pipeline.addLast("objectDecoder", new HuaShengProtocolDecoder(HuaShengProtocol.this)); } diff --git a/src/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/org/traccar/protocol/HuaShengProtocolDecoder.java index 88f23b28c..ae57ef296 100644 --- a/src/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -41,9 +42,9 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_HSO_REQ = 0x0002; public static final int MSG_HSO_RSP = 0x0003; - private void sendResponse(Channel channel, int type, int index, ChannelBuffer content) { + private void sendResponse(Channel channel, int type, int index, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(0xC0); response.writeShort(0x0100); response.writeShort(12 + (content != null ? content.readableBytes() : 0)); @@ -52,9 +53,10 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { response.writeInt(index); if (content != null) { response.writeBytes(content); + content.release(); } response.writeByte(0xC0); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -62,7 +64,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(1); // start marker buf.readUnsignedByte(); // flag @@ -80,10 +82,10 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { int subtype = buf.readUnsignedShort(); int length = buf.readUnsignedShort() - 4; if (subtype == 0x0003) { - String imei = buf.readBytes(length).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(length).toString(StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null && channel != null) { - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); content.writeByte(0); // success sendResponse(channel, MSG_LOGIN_RSP, index, content); } @@ -114,7 +116,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(status, 14)); position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - String time = buf.readBytes(12).toString(StandardCharsets.US_ASCII); + String time = buf.readSlice(12).toString(StandardCharsets.US_ASCII); DateBuilder dateBuilder = new DateBuilder() .setYear(Integer.parseInt(time.substring(0, 2))) diff --git a/src/org/traccar/protocol/HuabaoFrameDecoder.java b/src/org/traccar/protocol/HuabaoFrameDecoder.java index 8e9c9fe72..b520f6be9 100644 --- a/src/org/traccar/protocol/HuabaoFrameDecoder.java +++ b/src/org/traccar/protocol/HuabaoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,17 +15,17 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class HuabaoFrameDecoder extends FrameDecoder { +public class HuabaoFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 2) { return null; @@ -33,7 +33,7 @@ public class HuabaoFrameDecoder extends FrameDecoder { int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0x7e); if (index != -1) { - ChannelBuffer result = ChannelBuffers.buffer(index + 1 - buf.readerIndex()); + ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); while (buf.readerIndex() <= index) { int b = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/HuabaoProtocol.java b/src/org/traccar/protocol/HuabaoProtocol.java index c74cb58c7..113aa4b62 100644 --- a/src/org/traccar/protocol/HuabaoProtocol.java +++ b/src/org/traccar/protocol/HuabaoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -34,9 +33,9 @@ public class HuabaoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new HuabaoFrameDecoder()); pipeline.addLast("objectEncoder", new HuabaoProtocolEncoder()); pipeline.addLast("objectDecoder", new HuabaoProtocolDecoder(HuabaoProtocol.this)); diff --git a/src/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/org/traccar/protocol/HuabaoProtocolDecoder.java index 8643f39af..b92840dfc 100644 --- a/src/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; @@ -29,6 +31,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.TimeZone; public class HuabaoProtocolDecoder extends BaseProtocolDecoder { @@ -42,31 +46,34 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100; public static final int MSG_TERMINAL_AUTH = 0x0102; public static final int MSG_LOCATION_REPORT = 0x0200; + public static final int MSG_LOCATION_BATCH = 0x0704; public static final int MSG_OIL_CONTROL = 0XA006; public static final int RESULT_SUCCESS = 0; - public static ChannelBuffer formatMessage(int type, ChannelBuffer id, ChannelBuffer data) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + public static ByteBuf formatMessage(int type, ByteBuf id, ByteBuf data) { + ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x7e); buf.writeShort(type); buf.writeShort(data.readableBytes()); buf.writeBytes(id); buf.writeShort(1); // index buf.writeBytes(data); - buf.writeByte(Checksum.xor(buf.toByteBuffer(1, buf.readableBytes() - 1))); + data.release(); + buf.writeByte(Checksum.xor(buf.nioBuffer(1, buf.readableBytes() - 1))); buf.writeByte(0x7e); return buf; } private void sendGeneralResponse( - Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int type, int index) { + Channel channel, SocketAddress remoteAddress, ByteBuf id, int type, int index) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeShort(type); response.writeByte(RESULT_SUCCESS); - channel.write(formatMessage(MSG_GENERAL_RESPONSE, id, response), remoteAddress); + channel.writeAndFlush(new NetworkMessage( + formatMessage(MSG_GENERAL_RESPONSE, id, response), remoteAddress)); } } @@ -100,15 +107,15 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // start marker int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // body length - ChannelBuffer id = buf.readBytes(6); // phone number + ByteBuf id = buf.readSlice(6); // phone number int index = buf.readUnsignedShort(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(id)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); if (deviceSession == null) { return null; } @@ -116,11 +123,12 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_TERMINAL_REGISTER) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeByte(RESULT_SUCCESS); response.writeBytes("authentication".getBytes(StandardCharsets.US_ASCII)); - channel.write(formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, response), remoteAddress); + channel.writeAndFlush(new NetworkMessage( + formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, response), remoteAddress)); } } else if (type == MSG_TERMINAL_AUTH) { @@ -129,52 +137,77 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_LOCATION_REPORT) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + return decodeLocation(deviceSession, buf); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + } else if (type == MSG_LOCATION_BATCH) { - int flags = buf.readInt(); + return decodeLocationBatch(deviceSession, buf); - position.set(Position.KEY_IGNITION, BitUtil.check(flags, 0)); + } - position.setValid(BitUtil.check(flags, 1)); + return null; + } - double lat = buf.readUnsignedInt() * 0.000001; - double lon = buf.readUnsignedInt() * 0.000001; + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { - if (BitUtil.check(flags, 2)) { - position.setLatitude(-lat); - } else { - position.setLatitude(lat); - } + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - if (BitUtil.check(flags, 3)) { - position.setLongitude(-lon); - } else { - position.setLongitude(lon); - } + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); - position.setAltitude(buf.readShort()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort()); + int flags = buf.readInt(); - DateBuilder dateBuilder = new DateBuilder(TimeZone.getTimeZone("GMT+8")) - .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)); - position.setTime(dateBuilder.getDate()); + position.set(Position.KEY_IGNITION, BitUtil.check(flags, 0)); - // additional information + position.setValid(BitUtil.check(flags, 1)); - return position; + double lat = buf.readUnsignedInt() * 0.000001; + double lon = buf.readUnsignedInt() * 0.000001; + if (BitUtil.check(flags, 2)) { + position.setLatitude(-lat); + } else { + position.setLatitude(lat); } - return null; + if (BitUtil.check(flags, 3)) { + position.setLongitude(-lon); + } else { + position.setLongitude(lon); + } + + position.setAltitude(buf.readShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort()); + + DateBuilder dateBuilder = new DateBuilder(TimeZone.getTimeZone("GMT+8")) + .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)); + position.setTime(dateBuilder.getDate()); + + // additional information + + return position; + } + + private List<Position> decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf) { + + List<Position> positions = new LinkedList<>(); + + int count = buf.readUnsignedShort(); + buf.readUnsignedByte(); // location type + + for (int i = 0; i < count; i++) { + int endIndex = buf.readUnsignedShort() + buf.readerIndex(); + positions.add(decodeLocation(deviceSession, buf)); + buf.readerIndex(endIndex); + } + + return positions; } } diff --git a/src/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/org/traccar/protocol/HuabaoProtocolEncoder.java index d1889bf5e..a2702fec7 100644 --- a/src/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.helper.Log; @@ -30,24 +30,27 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - ChannelBuffer id = ChannelBuffers.wrappedBuffer( + ByteBuf id = Unpooled.wrappedBuffer( DataConverter.parseHex(getUniqueId(command.getDeviceId()))); - - ChannelBuffer data = ChannelBuffers.dynamicBuffer(); - byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - data.writeByte(0x01); - data.writeBytes(time); - return HuabaoProtocolDecoder.formatMessage(HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); - case Command.TYPE_ENGINE_RESUME: - data.writeByte(0x00); - data.writeBytes(time); - return HuabaoProtocolDecoder.formatMessage(HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); - default: - Log.warning(new UnsupportedOperationException(command.getType())); - return null; + try { + ByteBuf data = Unpooled.buffer(); + byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); + + switch (command.getType()) { + case Command.TYPE_ENGINE_STOP: + data.writeByte(0x01); + data.writeBytes(time); + return HuabaoProtocolDecoder.formatMessage(HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); + case Command.TYPE_ENGINE_RESUME: + data.writeByte(0x00); + data.writeBytes(time); + return HuabaoProtocolDecoder.formatMessage(HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + return null; + } + } finally { + id.release(); } } diff --git a/src/org/traccar/protocol/HunterProProtocol.java b/src/org/traccar/protocol/HunterProProtocol.java index 17352a0f3..8b81e8f22 100644 --- a/src/org/traccar/protocol/HunterProProtocol.java +++ b/src/org/traccar/protocol/HunterProProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class HunterProProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/HunterProProtocolDecoder.java b/src/org/traccar/protocol/HunterProProtocolDecoder.java index fa470c065..c166d151d 100644 --- a/src/org/traccar/protocol/HunterProProtocolDecoder.java +++ b/src/org/traccar/protocol/HunterProProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/IdplProtocol.java b/src/org/traccar/protocol/IdplProtocol.java index f90d3fe7f..2275aaeb2 100644 --- a/src/org/traccar/protocol/IdplProtocol.java +++ b/src/org/traccar/protocol/IdplProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -17,12 +17,11 @@ package org.traccar.protocol; import java.util.List; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; public class IdplProtocol extends BaseProtocol { @@ -33,9 +32,9 @@ public class IdplProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/IdplProtocolDecoder.java b/src/org/traccar/protocol/IdplProtocolDecoder.java index 9990e0da5..cf3c03d7f 100644 --- a/src/org/traccar/protocol/IdplProtocolDecoder.java +++ b/src/org/traccar/protocol/IdplProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -18,7 +18,7 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.util.regex.Pattern; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; diff --git a/src/org/traccar/protocol/IntellitracFrameDecoder.java b/src/org/traccar/protocol/IntellitracFrameDecoder.java index 49f8b4a5d..8322e65ba 100644 --- a/src/org/traccar/protocol/IntellitracFrameDecoder.java +++ b/src/org/traccar/protocol/IntellitracFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,10 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LineBasedFrameDecoder; +import org.traccar.NetworkMessage; public class IntellitracFrameDecoder extends LineBasedFrameDecoder { @@ -31,7 +31,7 @@ public class IntellitracFrameDecoder extends LineBasedFrameDecoder { // example of sync header: 0xFA 0xF8 0x1B 0x01 0x81 0x60 0x33 0x3C @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { // Check minimum length if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { @@ -40,13 +40,13 @@ public class IntellitracFrameDecoder extends LineBasedFrameDecoder { // Check for sync packet if (buf.getUnsignedShort(buf.readerIndex()) == 0xFAF8) { - ChannelBuffer syncMessage = buf.readBytes(8); - if (channel != null) { - channel.write(syncMessage); + ByteBuf syncMessage = buf.readRetainedSlice(8); + if (ctx != null && ctx.channel() != null) { + ctx.channel().writeAndFlush(new NetworkMessage(syncMessage, ctx.channel().remoteAddress())); } } - return super.decode(ctx, channel, buf); + return super.decode(ctx, buf); } } diff --git a/src/org/traccar/protocol/IntellitracProtocol.java b/src/org/traccar/protocol/IntellitracProtocol.java index 2d9421636..fc954625a 100644 --- a/src/org/traccar/protocol/IntellitracProtocol.java +++ b/src/org/traccar/protocol/IntellitracProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class IntellitracProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new IntellitracFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/org/traccar/protocol/IntellitracProtocolDecoder.java index 5b66fa7ec..58898f8fd 100644 --- a/src/org/traccar/protocol/IntellitracProtocolDecoder.java +++ b/src/org/traccar/protocol/IntellitracProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/Ivt401Protocol.java b/src/org/traccar/protocol/Ivt401Protocol.java index b58601ba1..dce0f2b79 100644 --- a/src/org/traccar/protocol/Ivt401Protocol.java +++ b/src/org/traccar/protocol/Ivt401Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class Ivt401Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Ivt401ProtocolDecoder(Ivt401Protocol.this)); diff --git a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java index d2f1d3d69..38dacb02b 100644 --- a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/JpKorjarFrameDecoder.java b/src/org/traccar/protocol/JpKorjarFrameDecoder.java index 33a1b3f36..0eb65c8ef 100644 --- a/src/org/traccar/protocol/JpKorjarFrameDecoder.java +++ b/src/org/traccar/protocol/JpKorjarFrameDecoder.java @@ -1,5 +1,6 @@ /* * Copyright 2016 Nyash (nyashh@gmail.com) + * Copyright 2018 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. @@ -15,16 +16,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class JpKorjarFrameDecoder extends FrameDecoder { +public class JpKorjarFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 80) { return null; @@ -40,7 +41,7 @@ public class JpKorjarFrameDecoder extends FrameDecoder { return null; } - return buf.readBytes(endIndex + 1); + return buf.readRetainedSlice(endIndex + 1); } } diff --git a/src/org/traccar/protocol/JpKorjarProtocol.java b/src/org/traccar/protocol/JpKorjarProtocol.java index c54994708..020575a7d 100644 --- a/src/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/org/traccar/protocol/JpKorjarProtocol.java @@ -1,5 +1,6 @@ /* * Copyright 2016 Nyash (nyashh@gmail.com) + * Copyright 2018 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. @@ -15,10 +16,9 @@ */ 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 io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,10 +31,9 @@ public class JpKorjarProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + serverList.add(new TrackerServer(false, this.getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new JpKorjarFrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new JpKorjarProtocolDecoder(JpKorjarProtocol.this)); diff --git a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/org/traccar/protocol/JpKorjarProtocolDecoder.java index 8766115ce..860e3ea23 100644 --- a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java +++ b/src/org/traccar/protocol/JpKorjarProtocolDecoder.java @@ -1,6 +1,6 @@ /*
* Copyright 2016 Nyash (nyashh@gmail.com)
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2018 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.
@@ -16,7 +16,7 @@ */
package org.traccar.protocol;
-import org.jboss.netty.channel.Channel;
+import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.helper.Parser;
diff --git a/src/org/traccar/protocol/Jt600FrameDecoder.java b/src/org/traccar/protocol/Jt600FrameDecoder.java index 261f46fe8..b5d060ecc 100644 --- a/src/org/traccar/protocol/Jt600FrameDecoder.java +++ b/src/org/traccar/protocol/Jt600FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; import java.text.ParseException; -public class Jt600FrameDecoder extends FrameDecoder { +public class Jt600FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; @@ -38,12 +38,12 @@ public class Jt600FrameDecoder extends FrameDecoder { boolean longFormat = buf.getUnsignedByte(buf.readerIndex() + 1) == 0x75; int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10; if (length <= buf.readableBytes()) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } else if (type == '(') { int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ')'); if (endIndex != -1) { - return buf.readBytes(endIndex + 1); + return buf.readRetainedSlice(endIndex + 1); } } else { throw new ParseException(null, 0); // unknown message diff --git a/src/org/traccar/protocol/Jt600Protocol.java b/src/org/traccar/protocol/Jt600Protocol.java index 8c71ca4f6..17fd4cb6b 100644 --- a/src/org/traccar/protocol/Jt600Protocol.java +++ b/src/org/traccar/protocol/Jt600Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,9 +36,9 @@ public class Jt600Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Jt600FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Jt600ProtocolEncoder()); diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index f5d8a79a4..109f8a68a 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; @@ -49,7 +50,42 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes / 60; } - private List<Position> decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + private void decodeStatus(Position position, ByteBuf buf) { + + int value = buf.readUnsignedByte(); + + position.set(Position.KEY_IGNITION, BitUtil.check(value, 0)); + position.set(Position.KEY_DOOR, BitUtil.check(value, 6)); + + value = buf.readUnsignedByte(); + + position.set(Position.KEY_CHARGE, BitUtil.check(value, 0)); + position.set(Position.KEY_BLOCKED, BitUtil.check(value, 1)); + + if (BitUtil.check(value, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + if (BitUtil.check(value, 3) || BitUtil.check(value, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); + } + if (BitUtil.check(value, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + + value = buf.readUnsignedByte(); + + if (BitUtil.check(value, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + } + if (BitUtil.check(value, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_TOW); + } + + buf.readUnsignedByte(); // reserved + + } + + private List<Position> decodeBinary(ByteBuf buf, Channel channel, SocketAddress remoteAddress) { List<Position> positions = new LinkedList<>(); @@ -57,7 +93,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { boolean longFormat = buf.getUnsignedByte(buf.readerIndex()) == 0x75; - String id = String.valueOf(Long.parseLong(ChannelBuffers.hexDump(buf.readBytes(5)))); + String id = String.valueOf(Long.parseLong(ByteBufUtil.hexDump(buf.readSlice(5)))); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; @@ -109,7 +145,15 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // vehicle id combined - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + int status = buf.readUnsignedShort(); + position.set(Position.KEY_ALARM, BitUtil.check(status, 1) ? Position.ALARM_GEOFENCE_ENTER : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 2) ? Position.ALARM_GEOFENCE_EXIT : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 3) ? Position.ALARM_POWER_CUT : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 4) ? Position.ALARM_VIBRATION : null); + position.set(Position.KEY_BLOCKED, BitUtil.check(status, 7)); + position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 3) ? Position.ALARM_LOW_BATTERY : null); + position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 6) ? Position.ALARM_FAULT : null); + position.set(Position.KEY_STATUS, status); int battery = buf.readUnsignedByte(); if (battery == 0xff) { @@ -152,7 +196,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int fuel = buf.readUnsignedByte() << 8; - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + decodeStatus(position, buf); position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); fuel += buf.readUnsignedByte(); @@ -297,9 +341,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { if (type.equals("U01") || type.equals("U02") || type.equals("U03")) { - channel.write("(S39)"); + channel.writeAndFlush(new NetworkMessage("(S39)", remoteAddress)); } else if (type.equals("U06")) { - channel.write("(S20)"); + channel.writeAndFlush(new NetworkMessage("(S20)", remoteAddress)); } } @@ -310,7 +354,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; char first = (char) buf.getByte(0); if (first == '$') { diff --git a/src/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/org/traccar/protocol/Jt600ProtocolEncoder.java index 377f104a3..1d868cbcf 100644 --- a/src/org/traccar/protocol/Jt600ProtocolEncoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -22,6 +22,7 @@ import org.traccar.helper.Log; import org.traccar.model.Command; public class Jt600ProtocolEncoder extends StringProtocolEncoder { + @Override protected Object encodeCommand(Command command) { @@ -42,4 +43,5 @@ public class Jt600ProtocolEncoder extends StringProtocolEncoder { return null; } + } diff --git a/src/org/traccar/protocol/KenjiProtocol.java b/src/org/traccar/protocol/KenjiProtocol.java index 8b196a9ed..15eb3d77a 100644 --- a/src/org/traccar/protocol/KenjiProtocol.java +++ b/src/org/traccar/protocol/KenjiProtocol.java @@ -1,5 +1,6 @@ /* - * Copyright 2016 by Carlos Alvarez (carlos.alvarez.rozas@gmail.com) + * Copyright 2016 Carlos Alvarez (carlos.alvarez.rozas@gmail.com) + * Copyright 2018 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. @@ -15,12 +16,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,12 +31,11 @@ public class KenjiProtocol extends BaseProtocol { super("kenji"); } - @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/KenjiProtocolDecoder.java b/src/org/traccar/protocol/KenjiProtocolDecoder.java index 374cb9c25..1fe1b6b9f 100644 --- a/src/org/traccar/protocol/KenjiProtocolDecoder.java +++ b/src/org/traccar/protocol/KenjiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/KhdProtocol.java b/src/org/traccar/protocol/KhdProtocol.java index 167727191..47a30de5a 100644 --- a/src/org/traccar/protocol/KhdProtocol.java +++ b/src/org/traccar/protocol/KhdProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -35,9 +34,9 @@ public class KhdProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(512, 3, 2)); pipeline.addLast("objectEncoder", new KhdProtocolEncoder()); pipeline.addLast("objectDecoder", new KhdProtocolDecoder(KhdProtocol.this)); diff --git a/src/org/traccar/protocol/KhdProtocolDecoder.java b/src/org/traccar/protocol/KhdProtocolDecoder.java index d1b5413e5..6aa4add9e 100644 --- a/src/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/org/traccar/protocol/KhdProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; @@ -34,19 +35,12 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private String readSerialNumber(ChannelBuffer buf) { + private String readSerialNumber(ByteBuf buf) { int b1 = buf.readUnsignedByte(); - int b2 = buf.readUnsignedByte(); - if (b2 > 0x80) { - b2 -= 0x80; - } - int b3 = buf.readUnsignedByte(); - if (b3 > 0x80) { - b3 -= 0x80; - } + int b2 = buf.readUnsignedByte() - 0x80; + int b3 = buf.readUnsignedByte() - 0x80; int b4 = buf.readUnsignedByte(); - String serialNumber = String.format("%02d%02d%02d%02d", b1, b2, b3, b4); - return String.valueOf(Long.parseLong(serialNumber)); + return String.format("%02d%02d%02d%02d", b1, b2, b3, b4); } public static final int MSG_LOGIN = 0xB1; @@ -62,7 +56,7 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte(); @@ -136,16 +130,16 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(4); // serial number buf.readByte(); // reserved - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(0x29); response.writeByte(0x29); // header response.writeByte(MSG_CONFIRMATION); response.writeShort(5); // size response.writeByte(buf.readUnsignedByte()); response.writeByte(type); response.writeByte(0); // reserved - response.writeByte(Checksum.xor(response.toByteBuffer())); + response.writeByte(Checksum.xor(response.nioBuffer())); response.writeByte(0x0D); // ending - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } diff --git a/src/org/traccar/protocol/KhdProtocolEncoder.java b/src/org/traccar/protocol/KhdProtocolEncoder.java index 618e43dad..9c0f0b67a 100644 --- a/src/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/org/traccar/protocol/KhdProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.Log; @@ -27,9 +27,9 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { public static final int MSG_CUT_OIL = 0x39; public static final int MSG_RESUME_OIL = 0x38; - private ChannelBuffer encodeCommand(int command) { + private ByteBuf encodeCommand(int command, String uniqueId) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x29); buf.writeByte(0x29); @@ -37,9 +37,14 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(command); buf.writeShort(6); // size - buf.writeInt(0); // terminal id + uniqueId = "00000000".concat(uniqueId); + uniqueId = uniqueId.substring(uniqueId.length() - 8); + buf.writeByte(Integer.parseInt(uniqueId.substring(0, 2))); + buf.writeByte(Integer.parseInt(uniqueId.substring(2, 4)) + 0x80); + buf.writeByte(Integer.parseInt(uniqueId.substring(4, 6)) + 0x80); + buf.writeByte(Integer.parseInt(uniqueId.substring(6, 8))); - buf.writeByte(Checksum.xor(buf.toByteBuffer())); + buf.writeByte(Checksum.xor(buf.nioBuffer())); buf.writeByte(0x0D); // ending return buf; @@ -48,11 +53,13 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { + String uniqueId = getUniqueId(command.getDeviceId()); + switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return encodeCommand(MSG_CUT_OIL); + return encodeCommand(MSG_CUT_OIL, uniqueId); case Command.TYPE_ENGINE_RESUME: - return encodeCommand(MSG_RESUME_OIL); + return encodeCommand(MSG_RESUME_OIL, uniqueId); default: Log.warning(new UnsupportedOperationException(command.getType())); break; diff --git a/src/org/traccar/protocol/L100FrameDecoder.java b/src/org/traccar/protocol/L100FrameDecoder.java index a597cbd7d..b7caa14f4 100644 --- a/src/org/traccar/protocol/L100FrameDecoder.java +++ b/src/org/traccar/protocol/L100FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,33 +15,46 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class L100FrameDecoder extends FrameDecoder { +public class L100FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - if (buf.readableBytes() < 80) { + if (buf.readableBytes() < 10) { return null; } - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02); - if (index == -1) { - index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04); + int header = buf.getByte(buf.readerIndex()); + boolean obd = header == 'L' || header == 'H'; + + int index; + if (obd) { + index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*'); + } else { + index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02); if (index == -1) { - return null; + index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04); + if (index == -1) { + return null; + } } } index += 2; // checksum - if (buf.readableBytes() >= index - buf.readerIndex()) { - return buf.readBytes(index - buf.readerIndex()); + if (buf.writerIndex() >= index) { + if (!obd) { + buf.skipBytes(2); // header + } + ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex() - 2); + buf.skipBytes(2); // footer + return frame; } return null; diff --git a/src/org/traccar/protocol/L100Protocol.java b/src/org/traccar/protocol/L100Protocol.java index 2bcef4caa..2d29bee40 100644 --- a/src/org/traccar/protocol/L100Protocol.java +++ b/src/org/traccar/protocol/L100Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,10 +31,12 @@ public class L100Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new L100FrameDecoder()); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new L100ProtocolDecoder(L100Protocol.this)); } }); diff --git a/src/org/traccar/protocol/L100ProtocolDecoder.java b/src/org/traccar/protocol/L100ProtocolDecoder.java index de966d7af..d9f830ec5 100644 --- a/src/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/org/traccar/protocol/L100ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -27,7 +28,6 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; public class L100ProtocolDecoder extends BaseProtocolDecoder { @@ -43,9 +43,9 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { .number("(dd)(dd)(dd)") // time (hhmmss.sss) .number(".(ddd)").optional() .expression(",([AV]),") // validity - .number("(dd)(dd.d+),") // latitude + .number("(d+)(dd.d+),") // latitude .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude + .number("(d+)(dd.d+),") // longitude .expression("([EW]),") .number("(d+.?d*)?,") // speed .number("(d+.?d*)?,") // course @@ -56,43 +56,75 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { .number("(d+.?d*|N.C),") // adc .expression("[^,]*,") // reserved .expression("[^,]*,") // reserved - .number("(d+.d+),") // odometer - .number("(d+.d+),") // temperature - .number("(d+.d+),") // battery - .number("(d+),") // gsm + .number("(d+.?d*),") // odometer + .number("(d+.?d*),") // temperature + .number("(d+.?d*),") // battery + .number("(d+),") // rssi .number("(d+),") // mcc .number("(d+),") // mnc .number("(x+),") // lac .number("(x+)") // cid + .any() .text("ATL") .compile(); + private static final Pattern PATTERN_OBD = new PatternBuilder() + .expression("[LH],") // archive + .text("ATL,") + .number("(d{15}),") // imei + .number("(d+),") // type + .number("(d+),") // index + .groupBegin() + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(dd)(dd)(dd),") // date (ddmmyy) + .expression("([AV]),") // validity + .number("(d+.d+);([NS]),") // latitude + .number("(d+.d+);([EW]),") // longitude + .number("(d+),") // speed + .number("(d+),") // course + .number("(d+.d+),") // odometer + .number("(d+.d+),") // battery + .number("(d+),") // rssi + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(d+),") // lac + .number("(x+),") // cid + .number("#(d)(d)(d)(d),") // status + .number("(d),") // overspeed + .text("ATL,") + .groupEnd("?") + .compile(); + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + String sentence = (String) msg; - buf.readUnsignedByte(); // start marker - buf.readUnsignedByte(); // type + if (sentence.startsWith("L") || sentence.startsWith("H")) { + return decodeObd(channel, remoteAddress, sentence); + } else { + return decodeNormal(channel, remoteAddress, sentence); + } + } - String sentence = buf.readBytes(buf.readableBytes() - 2).toString(StandardCharsets.US_ASCII); + private Object decodeNormal(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt(0)); position.setValid(parser.next().equals("A")); position.setLatitude(parser.nextCoordinate()); @@ -100,18 +132,88 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); position.set(Position.KEY_STATUS, parser.next()); position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0)); - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); + position.set(Position.KEY_ODOMETER, parser.nextDouble()); + position.set(Position.PREFIX_TEMP + 1, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + int rssi = parser.nextInt(); + if (rssi > 0) { + position.setNetwork(new Network(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi))); + } + + return position; + } + + private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - int rssi = parser.nextInt(0); + Parser parser = new Parser(PATTERN_OBD, sentence); + if (!parser.matches()) { + return null; + } + + String imei = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { + return null; + } + + int type = parser.nextInt(); + int index = parser.nextInt(); + + if (type == 1) { + if (channel != null) { + String response = "@" + imei + ",00," + index + ","; + response += "*" + (char) Checksum.xor(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(parser.nextInt()); + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + int rssi = parser.nextInt(); position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0), rssi))); + parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextHexInt(), rssi))); + + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + parser.next(); // reserved + + switch (parser.nextInt()) { + case 0: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 2: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 1: + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + break; + default: + break; + } + + position.set(Position.KEY_CHARGE, parser.nextInt() == 1); + + if (parser.nextInt() == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } return position; } diff --git a/src/org/traccar/protocol/LaipacProtocol.java b/src/org/traccar/protocol/LaipacProtocol.java index 45b803a0f..aafada331 100644 --- a/src/org/traccar/protocol/LaipacProtocol.java +++ b/src/org/traccar/protocol/LaipacProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class LaipacProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/LaipacProtocolDecoder.java b/src/org/traccar/protocol/LaipacProtocolDecoder.java index bfaff9ec4..9232cd6f0 100644 --- a/src/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/org/traccar/protocol/LaipacProtocolDecoder.java @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -93,7 +94,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; if (sentence.startsWith("$ECHK") && channel != null) { - channel.write(sentence + "\r\n"); // heartbeat + channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress)); // heartbeat return null; } @@ -114,7 +115,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); String status = parser.next(); - position.setValid(status.toUpperCase().equals("A")); + String upperCaseStatus = status.toUpperCase(); + position.setValid(upperCaseStatus.equals("A") || upperCaseStatus.equals("R") || upperCaseStatus.equals("P")); position.set(Position.KEY_STATUS, status); position.setLatitude(parser.nextCoordinate()); @@ -146,15 +148,15 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { if (event.equals("3")) { - channel.write("$AVCFG,00000000,d*31\r\n"); + channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,d*31\r\n", remoteAddress)); } else if (event.equals("X") || event.equals("4")) { - channel.write("$AVCFG,00000000,x*2D\r\n"); + channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,x*2D\r\n", remoteAddress)); } else if (event.equals("Z")) { - channel.write("$AVCFG,00000000,z*2F\r\n"); + channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,z*2F\r\n", remoteAddress)); } else if (Character.isLowerCase(status.charAt(0))) { String response = "$EAVACK," + event + "," + checksum; response += Checksum.nmea(response) + "\r\n"; - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } diff --git a/src/org/traccar/protocol/M2cProtocol.java b/src/org/traccar/protocol/M2cProtocol.java index 2c3187095..ef16108cd 100644 --- a/src/org/traccar/protocol/M2cProtocol.java +++ b/src/org/traccar/protocol/M2cProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class M2cProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(32 * 1024, ']')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/M2cProtocolDecoder.java b/src/org/traccar/protocol/M2cProtocolDecoder.java index c11136f4c..67b2accb9 100644 --- a/src/org/traccar/protocol/M2cProtocolDecoder.java +++ b/src/org/traccar/protocol/M2cProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/M2mProtocol.java b/src/org/traccar/protocol/M2mProtocol.java index 09393fed0..70dfc7b39 100644 --- a/src/org/traccar/protocol/M2mProtocol.java +++ b/src/org/traccar/protocol/M2mProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder; +import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class M2mProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new FixedLengthFrameDecoder(23)); pipeline.addLast("objectDecoder", new M2mProtocolDecoder(M2mProtocol.this)); } diff --git a/src/org/traccar/protocol/M2mProtocolDecoder.java b/src/org/traccar/protocol/M2mProtocolDecoder.java index b30919865..7bb704904 100644 --- a/src/org/traccar/protocol/M2mProtocolDecoder.java +++ b/src/org/traccar/protocol/M2mProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -36,7 +36,7 @@ public class M2mProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; // Remove offset for (int i = 0; i < buf.readableBytes(); i++) { diff --git a/src/org/traccar/protocol/MaestroProtocol.java b/src/org/traccar/protocol/MaestroProtocol.java index 5e0b69916..5a7cbcf4d 100644 --- a/src/org/traccar/protocol/MaestroProtocol.java +++ b/src/org/traccar/protocol/MaestroProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.FixedLengthFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class MaestroProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new FixedLengthFrameDecoder(160)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/MaestroProtocolDecoder.java b/src/org/traccar/protocol/MaestroProtocolDecoder.java index 6068c93b9..32072007e 100644 --- a/src/org/traccar/protocol/MaestroProtocolDecoder.java +++ b/src/org/traccar/protocol/MaestroProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/ManPowerProtocol.java b/src/org/traccar/protocol/ManPowerProtocol.java index 60ce8b282..5567cdccb 100644 --- a/src/org/traccar/protocol/ManPowerProtocol.java +++ b/src/org/traccar/protocol/ManPowerProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class ManPowerProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/org/traccar/protocol/ManPowerProtocolDecoder.java index 0b1c410c3..d1b6bdc72 100644 --- a/src/org/traccar/protocol/ManPowerProtocolDecoder.java +++ b/src/org/traccar/protocol/ManPowerProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/MegastekFrameDecoder.java b/src/org/traccar/protocol/MegastekFrameDecoder.java index d9cb07108..347fa24b1 100644 --- a/src/org/traccar/protocol/MegastekFrameDecoder.java +++ b/src/org/traccar/protocol/MegastekFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,19 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BufferUtil; import java.nio.charset.StandardCharsets; -public class MegastekFrameDecoder extends FrameDecoder { +public class MegastekFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; @@ -36,18 +36,18 @@ public class MegastekFrameDecoder extends FrameDecoder { if (Character.isDigit(buf.getByte(buf.readerIndex()))) { int length = 4 + Integer.parseInt(buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)); if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } else { while (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n') { buf.skipBytes(1); } - int delimiter = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("\r\n")); + int delimiter = BufferUtil.indexOf("\r\n", buf); if (delimiter == -1) { delimiter = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '!'); } if (delimiter != -1) { - ChannelBuffer result = buf.readBytes(delimiter - buf.readerIndex()); + ByteBuf result = buf.readRetainedSlice(delimiter - buf.readerIndex()); buf.skipBytes(1); return result; } diff --git a/src/org/traccar/protocol/MegastekProtocol.java b/src/org/traccar/protocol/MegastekProtocol.java index b28a05b92..862d1abd2 100644 --- a/src/org/traccar/protocol/MegastekProtocol.java +++ b/src/org/traccar/protocol/MegastekProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class MegastekProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new MegastekFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 91618b534..15f7be582 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -250,7 +250,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // mcc .number("(d+),") // mnc .number("(xxxx),") // lac - .number("(xxxx),") // cid + .number("(x+),") // cid .number("(d+)?,") // gsm .expression("([01]+)?,") // input .expression("([01]+)?,") // output @@ -268,7 +268,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { .number("(d+)?,") // rfid .expression("[^,]*,") .number("(d+)?,") // battery - .expression("([^,]*);") // alert + .expression("([^,]*)") // alert .any() .compile(); diff --git a/src/org/traccar/protocol/MeiligaoFrameDecoder.java b/src/org/traccar/protocol/MeiligaoFrameDecoder.java index 9340b6198..52f9ae26d 100644 --- a/src/org/traccar/protocol/MeiligaoFrameDecoder.java +++ b/src/org/traccar/protocol/MeiligaoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,21 +15,21 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class MeiligaoFrameDecoder extends FrameDecoder { +public class MeiligaoFrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_HEADER = 4; @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { // Strip not '$' (0x24) bytes from the beginning - while (buf.readable() && buf.getUnsignedByte(buf.readerIndex()) != 0x24) { + while (buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) != 0x24) { buf.readByte(); } @@ -37,7 +37,7 @@ public class MeiligaoFrameDecoder extends FrameDecoder { if (buf.readableBytes() >= MESSAGE_HEADER) { int length = buf.getUnsignedShort(buf.readerIndex() + 2); if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } diff --git a/src/org/traccar/protocol/MeiligaoProtocol.java b/src/org/traccar/protocol/MeiligaoProtocol.java index dbdd2619a..0b745f0c6 100644 --- a/src/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/org/traccar/protocol/MeiligaoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -35,22 +33,23 @@ public class MeiligaoProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_GEOFENCE, Command.TYPE_SET_TIMEZONE, + Command.TYPE_REQUEST_PHOTO, Command.TYPE_REBOOT_DEVICE); } @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new MeiligaoFrameDecoder()); pipeline.addLast("objectEncoder", new MeiligaoProtocolEncoder()); pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new MeiligaoProtocolEncoder()); pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 9f7b8abf7..30905076e 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,12 +15,14 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -30,12 +32,16 @@ import org.traccar.model.Position; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { + private Map<Byte, ByteBuf> photos = new HashMap<>(); + public MeiligaoProtocolDecoder(MeiligaoProtocol protocol) { super(protocol); } @@ -135,7 +141,20 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_OBD_RT = 0x9901; public static final int MSG_OBD_RTA = 0x9902; - private DeviceSession identify(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + public static final int MSG_TRACK_ON_DEMAND = 0x4101; + public static final int MSG_TRACK_BY_INTERVAL = 0x4102; + public static final int MSG_MOVEMENT_ALARM = 0x4106; + public static final int MSG_OUTPUT_CONTROL = 0x4115; + public static final int MSG_TIME_ZONE = 0x4132; + public static final int MSG_TAKE_PHOTO = 0x4151; + public static final int MSG_UPLOAD_PHOTO = 0x0800; + public static final int MSG_UPLOAD_PHOTO_RESPONSE = 0x8801; + public static final int MSG_DATA_PHOTO = 0x9988; + public static final int MSG_POSITION_IMAGE = 0x9977; + public static final int MSG_UPLOAD_COMPLETE = 0x0f80; + public static final int MSG_REBOOT_GPS = 0x4902; + + private DeviceSession identify(ByteBuf buf, Channel channel, SocketAddress remoteAddress) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < 7; i++) { @@ -166,10 +185,10 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } private static void sendResponse( - Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int type, ChannelBuffer msg) { + Channel channel, SocketAddress remoteAddress, ByteBuf id, int type, ByteBuf msg) { if (channel != null) { - ChannelBuffer buf = ChannelBuffers.buffer( + ByteBuf buf = Unpooled.buffer( 2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2); buf.writeByte('@'); @@ -178,18 +197,19 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { buf.writeBytes(id); buf.writeShort(type); buf.writeBytes(msg); - buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.toByteBuffer())); + msg.release(); + buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.nioBuffer())); buf.writeByte('\r'); buf.writeByte('\n'); - channel.write(buf, remoteAddress); + channel.writeAndFlush(new NetworkMessage(buf, remoteAddress)); } } private String getServer(Channel channel) { String server = Context.getConfig().getString(getProtocolName() + ".server"); - if (server == null) { - InetSocketAddress address = (InetSocketAddress) channel.getLocalAddress(); + if (server == null && channel != null) { + InetSocketAddress address = (InetSocketAddress) channel.localAddress(); server = address.getAddress().getHostAddress() + ":" + address.getPort(); } return server; @@ -252,7 +272,15 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextDouble(0)); } - position.set(Position.KEY_STATUS, parser.next()); + if (parser.hasNext()) { + int status = parser.nextHexInt(); + for (int i = 1; i <= 5; i++) { + position.set(Position.PREFIX_OUT + i, BitUtil.check(status, i - 1)); + } + for (int i = 1; i <= 5; i++) { + position.set(Position.PREFIX_IN + i, BitUtil.check(status, i - 1 + 8)); + } + } for (int i = 1; i <= 8; i++) { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); @@ -302,7 +330,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.set("drivingRange", parser.nextDouble()); position.set(Position.KEY_ODOMETER, parser.nextDouble()); position.set("singleFuelConsumption", parser.nextDouble()); - position.set("totalFuelConsumption", parser.nextDouble()); + position.set(Position.KEY_FUEL_USED, parser.nextDouble()); position.set(Position.KEY_DTCS, parser.nextInt()); position.set("hardAccelerationCount", parser.nextInt()); position.set("hardBrakingCount", parser.nextInt()); @@ -331,7 +359,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { return position; } - private List<Position> decodeRetransmission(ChannelBuffer buf, DeviceSession deviceSession) { + private List<Position> decodeRetransmission(ByteBuf buf, DeviceSession deviceSession) { List<Position> positions = new LinkedList<>(); int count = buf.readUnsignedByte(); @@ -344,7 +372,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { endIndex = buf.writerIndex() - 4; } - String sentence = buf.readBytes(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); + String sentence = buf.readSlice(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -368,27 +396,35 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readShort(); // length - ChannelBuffer id = buf.readBytes(7); + ByteBuf id = buf.readSlice(7); int command = buf.readUnsignedShort(); - ChannelBuffer response; - if (channel != null) { - if (command == MSG_LOGIN) { - response = ChannelBuffers.wrappedBuffer(new byte[]{0x01}); - sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response); - return null; - } else if (command == MSG_HEARTBEAT) { - response = ChannelBuffers.wrappedBuffer(new byte[]{0x01}); - sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response); - return null; - } else if (command == MSG_SERVER) { - response = ChannelBuffers.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII); - sendResponse(channel, remoteAddress, id, MSG_SERVER, response); - return null; - } + if (command == MSG_LOGIN) { + ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01}); + sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response); + return null; + } else if (command == MSG_HEARTBEAT) { + ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01}); + sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response); + return null; + } else if (command == MSG_SERVER) { + ByteBuf response = Unpooled.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII); + sendResponse(channel, remoteAddress, id, MSG_SERVER, response); + return null; + } else if (command == MSG_UPLOAD_PHOTO) { + byte imageIndex = buf.readByte(); + photos.put(imageIndex, Unpooled.buffer()); + ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex}); + sendResponse(channel, remoteAddress, id, MSG_UPLOAD_PHOTO_RESPONSE, response); + return null; + } else if (command == MSG_UPLOAD_COMPLETE) { + byte imageIndex = buf.readByte(); + ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex, 0, 0}); + sendResponse(channel, remoteAddress, id, MSG_RETRANSMISSION, response); + return null; } DeviceSession deviceSession = identify(id, channel, remoteAddress); @@ -396,7 +432,18 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { return null; } - if (command == MSG_RETRANSMISSION) { + if (command == MSG_DATA_PHOTO) { + + byte imageIndex = buf.readByte(); + buf.readUnsignedShort(); // image footage + buf.readUnsignedByte(); // total packets + buf.readUnsignedByte(); // packet index + + photos.get(imageIndex).writeBytes(buf, buf.readableBytes() - 2 - 2); + + return null; + + } else if (command == MSG_RETRANSMISSION) { return decodeRetransmission(buf, deviceSession); @@ -404,6 +451,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + if (command == MSG_ALARM) { short alarmCode = buf.readUnsignedByte(); position.set(Position.KEY_ALARM, decodeAlarm(alarmCode)); @@ -414,11 +463,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } } else if (command == MSG_POSITION_LOGGED) { buf.skipBytes(6); - } - - position.setDeviceId(deviceSession.getDeviceId()); - - if (command == MSG_RFID) { + } else if (command == MSG_RFID) { for (int i = 0; i < 15; i++) { long rfid = buf.readUnsignedInt(); if (rfid != 0) { @@ -427,23 +472,37 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_DRIVER_UNIQUE_ID, card); } } + } else if (command == MSG_POSITION_IMAGE) { + byte imageIndex = buf.readByte(); + buf.readUnsignedByte(); // image upload type + String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + ByteBuf photo = photos.remove(imageIndex); + try { + position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + } finally { + photo.release(); + } } String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, StandardCharsets.US_ASCII); - if (command == MSG_POSITION || command == MSG_POSITION_LOGGED || command == MSG_ALARM) { - return decodeRegular(position, sentence); - } else if (command == MSG_RFID) { - return decodeRfid(position, sentence); - } else if (command == MSG_OBD_RT) { - return decodeObd(position, sentence); - } else if (command == MSG_OBD_RTA) { - return decodeObdA(position, sentence); + switch (command) { + case MSG_POSITION: + case MSG_POSITION_LOGGED: + case MSG_ALARM: + case MSG_POSITION_IMAGE: + return decodeRegular(position, sentence); + case MSG_RFID: + return decodeRfid(position, sentence); + case MSG_OBD_RT: + return decodeObd(position, sentence); + case MSG_OBD_RTA: + return decodeObdA(position, sentence); + default: + return null; } } - - return null; } } diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java index 340d947e3..6052b2617 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; @@ -28,16 +28,9 @@ import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { - public static final int MSG_TRACK_ON_DEMAND = 0x4101; - public static final int MSG_TRACK_BY_INTERVAL = 0x4102; - public static final int MSG_MOVEMENT_ALARM = 0x4106; - public static final int MSG_OUTPUT_CONTROL = 0x4115; - public static final int MSG_TIME_ZONE = 0x4132; - public static final int MSG_REBOOT_GPS = 0x4902; + private ByteBuf encodeContent(long deviceId, int type, ByteBuf content) { - private ChannelBuffer encodeContent(long deviceId, int type, ChannelBuffer content) { - - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte('@'); buf.writeByte('@'); @@ -50,7 +43,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { buf.writeBytes(content); - buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.toByteBuffer())); + buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.nioBuffer())); buf.writeByte('\r'); buf.writeByte('\n'); @@ -61,29 +54,31 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), MSG_TRACK_ON_DEMAND, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_ON_DEMAND, content); case Command.TYPE_POSITION_PERIODIC: content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); - return encodeContent(command.getDeviceId(), MSG_TRACK_BY_INTERVAL, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); case Command.TYPE_ENGINE_STOP: content.writeByte(0x01); - return encodeContent(command.getDeviceId(), MSG_OUTPUT_CONTROL, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL, content); case Command.TYPE_ENGINE_RESUME: content.writeByte(0x00); - return encodeContent(command.getDeviceId(), MSG_OUTPUT_CONTROL, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL, content); case Command.TYPE_ALARM_GEOFENCE: content.writeShort(command.getInteger(Command.KEY_RADIUS)); - return encodeContent(command.getDeviceId(), MSG_MOVEMENT_ALARM, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_MOVEMENT_ALARM, content); case Command.TYPE_SET_TIMEZONE: int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; content.writeBytes(String.valueOf(offset).getBytes(StandardCharsets.US_ASCII)); - return encodeContent(command.getDeviceId(), MSG_TIME_ZONE, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TIME_ZONE, content); + case Command.TYPE_REQUEST_PHOTO: + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TAKE_PHOTO, content); case Command.TYPE_REBOOT_DEVICE: - return encodeContent(command.getDeviceId(), MSG_REBOOT_GPS, content); + return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_REBOOT_GPS, content); default: Log.warning(new UnsupportedOperationException(command.getType())); break; diff --git a/src/org/traccar/protocol/MeitrackFrameDecoder.java b/src/org/traccar/protocol/MeitrackFrameDecoder.java index 1eb0dae0f..d122bca0c 100644 --- a/src/org/traccar/protocol/MeitrackFrameDecoder.java +++ b/src/org/traccar/protocol/MeitrackFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; import java.nio.charset.StandardCharsets; -public class MeitrackFrameDecoder extends FrameDecoder { +public class MeitrackFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; @@ -37,7 +37,7 @@ public class MeitrackFrameDecoder extends FrameDecoder { int length = index - buf.readerIndex() + Integer.parseInt( buf.toString(buf.readerIndex() + 3, index - buf.readerIndex() - 3, StandardCharsets.US_ASCII)); if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index e89825da5..b9be2a8fd 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,15 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class MeitrackProtocol extends BaseProtocol { @@ -42,27 +39,23 @@ public class MeitrackProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new MeitrackFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); - server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { + }); + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 6fee0fd9f..465cfd9fa 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,12 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -38,7 +39,7 @@ import java.util.regex.Pattern; public class MeitrackProtocolDecoder extends BaseProtocolDecoder { - private ChannelBuffer photo; + private ByteBuf photo; public MeitrackProtocolDecoder(MeitrackProtocol protocol) { super(protocol); @@ -119,7 +120,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII)); if (!parser.matches()) { @@ -270,7 +271,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } - private List<Position> decodeBinaryC(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List<Position> decodeBinaryC(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { List<Position> positions = new LinkedList<>(); String flag = buf.toString(2, 1, StandardCharsets.US_ASCII); @@ -291,38 +292,38 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - position.setLatitude(buf.readInt() * 0.000001); - position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readIntLE() * 0.000001); + position.setLongitude(buf.readIntLE() * 0.000001); - position.setTime(new Date((946684800 + buf.readUnsignedInt()) * 1000)); // 946684800 = 2000-01-01 + position.setTime(new Date((946684800 + buf.readUnsignedIntLE()) * 1000)); // 946684800 = 2000-01-01 position.setValid(buf.readUnsignedByte() == 1); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); int rssi = buf.readUnsignedByte(); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - position.setCourse(buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1); + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE() * 0.1); - position.setAltitude(buf.readUnsignedShort()); + position.setAltitude(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - position.set("runtime", buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set("runtime", buf.readUnsignedIntLE()); position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), + buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), rssi))); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE()); - buf.readUnsignedInt(); // geo-fence + buf.readUnsignedIntLE(); // geo-fence positions.add(position); } @@ -337,17 +338,17 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } command.append(String.format("%02x", checksum & 0xff).toUpperCase()); command.append("\r\n"); - channel.write(command.toString()); // delete processed data + channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data } return positions; } - private List<Position> decodeBinaryE(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List<Position> decodeBinaryE(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { List<Position> positions = new LinkedList<>(); buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',') + 1); - String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); buf.skipBytes(1 + 3 + 1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); @@ -355,15 +356,15 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { return null; } - buf.readUnsignedInt(); // remaining cache - int count = buf.readUnsignedShort(); + buf.readUnsignedIntLE(); // remaining cache + int count = buf.readUnsignedShortLE(); for (int i = 0; i < count; i++) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedShort(); // length - buf.readUnsignedShort(); // index + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // index int paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { @@ -392,22 +393,22 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int id = buf.readUnsignedByte(); switch (id) { case 0x08: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); break; case 0x09: - position.setCourse(buf.readUnsignedShort() * 0.1); + position.setCourse(buf.readUnsignedShortLE()); break; case 0x0B: - position.setAltitude(buf.readShort()); + position.setAltitude(buf.readShortLE()); break; case 0x19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); break; case 0x1A: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); break; default: - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); break; } } @@ -417,19 +418,19 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int id = buf.readUnsignedByte(); switch (id) { case 0x02: - position.setLatitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readIntLE() * 0.000001); break; case 0x03: - position.setLongitude(buf.readInt() * 0.000001); + position.setLongitude(buf.readIntLE() * 0.000001); break; case 0x04: - position.setTime(new Date((946684800 + buf.readUnsignedInt()) * 1000)); // 2000-01-01 + position.setTime(new Date((946684800 + buf.readUnsignedIntLE()) * 1000)); // 2000-01-01 break; case 0x0D: - position.set("runtime", buf.readUnsignedInt()); + position.set("runtime", buf.readUnsignedIntLE()); break; default: - buf.readUnsignedInt(); + buf.readUnsignedIntLE(); break; } } @@ -446,13 +447,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { return positions; } - private void requestPhotoPacket(Channel channel, String imei, String file, int index) { + private void requestPhotoPacket(Channel channel, SocketAddress socketAddress, String imei, String file, int index) { if (channel != null) { String content = "D00," + file + "," + index; int length = 1 + imei.length() + 1 + content.length() + 5; String response = String.format("@@O%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, socketAddress)); } } @@ -460,7 +461,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); String imei = buf.toString(index + 1, 15, StandardCharsets.US_ASCII); @@ -470,7 +471,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { switch (type) { case "D00": if (photo == null) { - photo = ChannelBuffers.dynamicBuffer(); + photo = Unpooled.buffer(); } index = index + 1 + type.length() + 1; @@ -484,7 +485,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int current = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII)); buf.readerIndex(endIndex + 1); - photo.writeBytes(buf.readBytes(buf.readableBytes() - 1 - 2 - 2)); + photo.writeBytes(buf.readSlice(buf.readableBytes() - 1 - 2 - 2)); if (current == total - 1) { Position position = new Position(getProtocolName()); @@ -493,18 +494,19 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + photo.release(); photo = null; return position; } else { if ((current + 1) % 8 == 0) { - requestPhotoPacket(channel, imei, file, current + 1); + requestPhotoPacket(channel, remoteAddress, imei, file, current + 1); } return null; } case "D03": - photo = ChannelBuffers.dynamicBuffer(); - requestPhotoPacket(channel, imei, "camera_picture.jpg", 0); + photo = Unpooled.buffer(); + requestPhotoPacket(channel, remoteAddress, imei, "camera_picture.jpg", 0); return null; case "CCC": return decodeBinaryC(channel, remoteAddress, buf); diff --git a/src/org/traccar/protocol/MiniFinderProtocol.java b/src/org/traccar/protocol/MiniFinderProtocol.java index c36acb238..05641dcbe 100644 --- a/src/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/org/traccar/protocol/MiniFinderProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -46,9 +45,9 @@ public class MiniFinderProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java index ab046eca3..d7af66ba7 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/Mta6Protocol.java b/src/org/traccar/protocol/Mta6Protocol.java index 65a48808d..e0b3f6063 100644 --- a/src/org/traccar/protocol/Mta6Protocol.java +++ b/src/org/traccar/protocol/Mta6Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.Context; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,11 +33,12 @@ public class Mta6Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(65535)); pipeline.addLast("objectDecoder", new Mta6ProtocolDecoder( Mta6Protocol.this, !Context.getConfig().getBoolean(getName() + ".can"))); } diff --git a/src/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/org/traccar/protocol/Mta6ProtocolDecoder.java index c26e00c56..94b624612 100644 --- a/src/org/traccar/protocol/Mta6ProtocolDecoder.java +++ b/src/org/traccar/protocol/Mta6ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,20 +15,22 @@ */ 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.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 io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Log; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; @@ -47,30 +49,28 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { } private void sendContinue(Channel channel) { - HttpResponse response = new DefaultHttpResponse( + FullHttpResponse response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } private void sendResponse(Channel channel, short packetId, short packetCount) { - HttpResponse response = new DefaultHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - - ChannelBuffer begin = ChannelBuffers.copiedBuffer("#ACK#", StandardCharsets.US_ASCII); - ChannelBuffer end = ChannelBuffers.directBuffer(3); + ByteBuf begin = Unpooled.copiedBuffer("#ACK#", StandardCharsets.US_ASCII); + ByteBuf end = Unpooled.buffer(3); end.writeByte(packetId); end.writeByte(packetCount); end.writeByte(0); - response.setContent(ChannelBuffers.wrappedBuffer(begin, end)); - channel.write(response); + FullHttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(begin, end)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } private static class FloatReader { private int previousFloat; - public float readFloat(ChannelBuffer buf) { + public float readFloat(ByteBuf buf) { switch (buf.getUnsignedByte(buf.readerIndex()) >> 6) { case 0: previousFloat = buf.readInt() << 2; @@ -97,7 +97,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { private long weekNumber; - public Date readTime(ChannelBuffer buf) { + public Date readTime(ByteBuf buf) { long weekTime = (long) (readFloat(buf) * 1000); if (weekNumber == 0) { weekNumber = buf.readUnsignedShort(); @@ -111,7 +111,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { } - private List<Position> parseFormatA(DeviceSession deviceSession, ChannelBuffer buf) { + private List<Position> parseFormatA(DeviceSession deviceSession, ByteBuf buf) { List<Position> positions = new LinkedList<>(); FloatReader latitudeReader = new FloatReader(); @@ -119,7 +119,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { TimeReader timeReader = new TimeReader(); try { - while (buf.readable()) { + while (buf.isReadable()) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -198,7 +198,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { return positions; } - private Position parseFormatA1(DeviceSession deviceSession, ChannelBuffer buf) { + private Position parseFormatA1(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -231,7 +231,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(flags, 1)) { position.set(Position.KEY_FUEL_CONSUMPTION, new FloatReader().readFloat(buf)); - position.set(Position.KEY_HOURS, new FloatReader().readFloat(buf)); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(new FloatReader().readFloat(buf))); position.set("tank", buf.readUnsignedByte() * 0.4); } @@ -277,8 +277,8 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - ChannelBuffer buf = request.getContent(); + FullHttpRequest request = (FullHttpRequest) msg; + ByteBuf buf = request.content(); buf.skipBytes("id=".length()); int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '&'); @@ -308,7 +308,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { } else { return parseFormatA(deviceSession, buf); } - } //else if (0x34 0x38 0x4F 0x59) + } // else if (0x34 0x38 0x4F 0x59) return null; } diff --git a/src/org/traccar/protocol/MtxProtocol.java b/src/org/traccar/protocol/MtxProtocol.java index 58b2361cd..2f33909db 100644 --- a/src/org/traccar/protocol/MtxProtocol.java +++ b/src/org/traccar/protocol/MtxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class MtxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/MtxProtocolDecoder.java b/src/org/traccar/protocol/MtxProtocolDecoder.java index 412eac493..18bce399f 100644 --- a/src/org/traccar/protocol/MtxProtocolDecoder.java +++ b/src/org/traccar/protocol/MtxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; @@ -60,7 +61,7 @@ public class MtxProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { if (channel != null) { - channel.write("#ACK"); + channel.writeAndFlush(new NetworkMessage("#ACK", remoteAddress)); } Parser parser = new Parser(PATTERN, (String) msg); diff --git a/src/org/traccar/protocol/MxtFrameDecoder.java b/src/org/traccar/protocol/MxtFrameDecoder.java index b2cd6de93..d70e92da1 100644 --- a/src/org/traccar/protocol/MxtFrameDecoder.java +++ b/src/org/traccar/protocol/MxtFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,21 +15,17 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -import java.nio.ByteOrder; - -public class MxtFrameDecoder extends FrameDecoder { +public class MxtFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 2) { return null; @@ -37,7 +33,7 @@ public class MxtFrameDecoder extends FrameDecoder { int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0x04); if (index != -1) { - ChannelBuffer result = ChannelBuffers.buffer(ByteOrder.LITTLE_ENDIAN, index + 1 - buf.readerIndex()); + ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); while (buf.readerIndex() <= index) { int b = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/MxtProtocol.java b/src/org/traccar/protocol/MxtProtocol.java index 03c1da71e..8bfb958ab 100644 --- a/src/org/traccar/protocol/MxtProtocol.java +++ b/src/org/traccar/protocol/MxtProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class MxtProtocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class MxtProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new MxtFrameDecoder()); pipeline.addLast("objectDecoder", new MxtProtocolDecoder(MxtProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java index 9fe1924c0..d6029c6d0 100644 --- a/src/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/org/traccar/protocol/MxtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; @@ -27,7 +28,6 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; public class MxtProtocolDecoder extends BaseProtocolDecoder { @@ -41,17 +41,17 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { private static void sendResponse(Channel channel, int device, long id, int crc) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + ByteBuf response = Unpooled.buffer(); response.writeByte(device); response.writeByte(MSG_ACK); - response.writeInt((int) id); - response.writeShort(crc); - response.writeShort(Checksum.crc16( - Checksum.CRC16_XMODEM, response.toByteBuffer())); + response.writeIntLE((int) id); + response.writeShortLE(crc); + response.writeShortLE(Checksum.crc16( + Checksum.CRC16_XMODEM, response.nioBuffer())); - ChannelBuffer encoded = ChannelBuffers.dynamicBuffer(); + ByteBuf encoded = Unpooled.buffer(); encoded.writeByte(0x01); // header - while (response.readable()) { + while (response.isReadable()) { int b = response.readByte(); if (b == 0x01 || b == 0x04 || b == 0x10 || b == 0x11 || b == 0x13) { encoded.writeByte(0x10); @@ -59,8 +59,9 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { } encoded.writeByte(b); } + response.release(); encoded.writeByte(0x04); // ending - channel.write(encoded); + channel.writeAndFlush(new NetworkMessage(encoded, channel.remoteAddress())); } } @@ -68,13 +69,13 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // start int device = buf.readUnsignedByte(); // device descriptor int type = buf.readUnsignedByte(); - long id = buf.readUnsignedInt(); + long id = buf.readUnsignedIntLE(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); if (deviceSession == null) { return null; @@ -88,11 +89,11 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // protocol int infoGroups = buf.readUnsignedByte(); - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); DateBuilder dateBuilder = new DateBuilder().setDate(2000, 1, 1); - long date = buf.readUnsignedInt(); + long date = buf.readUnsignedIntLE(); long days = BitUtil.from(date, 6 + 6 + 5); long hours = BitUtil.between(date, 6 + 6, 6 + 6 + 5); @@ -104,10 +105,10 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { position.setTime(dateBuilder.getDate()); position.setValid(true); - position.setLatitude(buf.readInt() / 1000000.0); - position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readIntLE() / 1000000.0); + position.setLongitude(buf.readIntLE() / 1000000.0); - long flags = buf.readUnsignedInt(); + long flags = buf.readUnsignedIntLE(); position.set(Position.KEY_IGNITION, BitUtil.check(flags, 0)); if (BitUtil.check(flags, 1)) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); @@ -115,7 +116,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_INPUT, BitUtil.between(flags, 2, 7)); position.set(Position.KEY_OUTPUT, BitUtil.between(flags, 7, 10)); position.setCourse(BitUtil.between(flags, 10, 13) * 45); - //position.setValid(BitUtil.check(flags, 15)); + // position.setValid(BitUtil.check(flags, 15)); position.set(Position.KEY_CHARGE, BitUtil.check(flags, 20)); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); @@ -135,34 +136,34 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HDOP, buf.readUnsignedByte()); position.setAccuracy(buf.readUnsignedByte()); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - buf.readUnsignedShort(); // time since boot + buf.readUnsignedShortLE(); // time since boot position.set(Position.KEY_POWER, buf.readUnsignedByte()); position.set(Position.PREFIX_TEMP + 1, buf.readByte()); } if (BitUtil.check(infoGroups, 3)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); } if (BitUtil.check(infoGroups, 4)) { - position.set(Position.KEY_HOURS, buf.readUnsignedInt()); + position.set(Position.KEY_HOURS, UnitsConverter.msFromMinutes(buf.readUnsignedIntLE())); } if (BitUtil.check(infoGroups, 5)) { - buf.readUnsignedInt(); // reason + buf.readUnsignedIntLE(); // reason } if (BitUtil.check(infoGroups, 6)) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE()); } if (BitUtil.check(infoGroups, 7)) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedInt())); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); } buf.readerIndex(buf.writerIndex() - 3); - sendResponse(channel, device, id, buf.readUnsignedShort()); + sendResponse(channel, device, id, buf.readUnsignedShortLE()); return position; } diff --git a/src/org/traccar/protocol/NavigilFrameDecoder.java b/src/org/traccar/protocol/NavigilFrameDecoder.java index 34eb28941..e8b6bea52 100644 --- a/src/org/traccar/protocol/NavigilFrameDecoder.java +++ b/src/org/traccar/protocol/NavigilFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,21 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class NavigilFrameDecoder extends FrameDecoder { +public class NavigilFrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_HEADER = 20; private static final long PREAMBLE = 0x2477F5F6; @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { // Check minimum length if (buf.readableBytes() < MESSAGE_HEADER) { @@ -38,18 +36,18 @@ public class NavigilFrameDecoder extends FrameDecoder { // Check for preamble boolean hasPreamble = false; - if (buf.getUnsignedInt(buf.readerIndex()) == PREAMBLE) { + if (buf.getUnsignedIntLE(buf.readerIndex()) == PREAMBLE) { hasPreamble = true; } // Check length and return buffer - int length = buf.getUnsignedShort(buf.readerIndex() + 6); + int length = buf.getUnsignedShortLE(buf.readerIndex() + 6); if (buf.readableBytes() >= length) { if (hasPreamble) { - buf.readUnsignedInt(); + buf.readUnsignedIntLE(); length -= 4; } - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/NavigilProtocol.java b/src/org/traccar/protocol/NavigilProtocol.java index 6646c6cc6..82f4af17d 100644 --- a/src/org/traccar/protocol/NavigilProtocol.java +++ b/src/org/traccar/protocol/NavigilProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class NavigilProtocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class NavigilProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new NavigilFrameDecoder()); pipeline.addLast("objectDecoder", new NavigilProtocolDecoder(NavigilProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/NavigilProtocolDecoder.java b/src/org/traccar/protocol/NavigilProtocolDecoder.java index 4f3b4ad74..19eb37c27 100644 --- a/src/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/org/traccar/protocol/NavigilProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.util.Date; public class NavigilProtocolDecoder extends BaseProtocolDecoder { @@ -60,106 +60,106 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { private int senderSequenceNumber = 1; private void sendAcknowledgment(Channel channel, int sequenceNumber) { - ChannelBuffer data = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 4); - data.writeShort(sequenceNumber); - data.writeShort(0); // OK + ByteBuf data = Unpooled.buffer(4); + data.writeShortLE(sequenceNumber); + data.writeShortLE(0); // OK - ChannelBuffer header = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 20); + ByteBuf header = Unpooled.buffer(20); header.writeByte(1); header.writeByte(0); - header.writeShort(senderSequenceNumber++); - header.writeShort(MSG_ACKNOWLEDGEMENT); - header.writeShort(header.capacity() + data.capacity()); - header.writeShort(0); - header.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, data.toByteBuffer())); - header.writeInt(0); - header.writeInt((int) (System.currentTimeMillis() / 1000) + LEAP_SECONDS_DELTA); + header.writeShortLE(senderSequenceNumber++); + header.writeShortLE(MSG_ACKNOWLEDGEMENT); + header.writeShortLE(header.capacity() + data.capacity()); + header.writeShortLE(0); + header.writeShortLE(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, data.nioBuffer())); + header.writeIntLE(0); + header.writeIntLE((int) (System.currentTimeMillis() / 1000) + LEAP_SECONDS_DELTA); if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer(header, data)); + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(header, data), channel.remoteAddress())); } } private Position parseUnitReport( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber) { Position position = new Position(getProtocolName()); position.setValid(true); position.set(Position.KEY_INDEX, sequenceNumber); position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedShort(); // report trigger - position.set(Position.KEY_FLAGS, buf.readUnsignedShort()); + buf.readUnsignedShortLE(); // report trigger + position.set(Position.KEY_FLAGS, buf.readUnsignedShortLE()); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - position.setAltitude(buf.readUnsignedShort()); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setAltitude(buf.readUnsignedShortLE()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedShort()); - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShort()); - position.set("gpsAntennaState", buf.readUnsignedShort()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedShortLE()); + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShortLE()); + position.set("gpsAntennaState", buf.readUnsignedShortLE()); - position.setSpeed(buf.readUnsignedShort() * 0.194384); - position.setCourse(buf.readUnsignedShort()); + position.setSpeed(buf.readUnsignedShortLE() * 0.194384); + position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - position.set(Position.KEY_DISTANCE, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set(Position.KEY_DISTANCE, buf.readUnsignedIntLE()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - position.set(Position.KEY_CHARGE, buf.readUnsignedShort()); + position.set(Position.KEY_CHARGE, buf.readUnsignedShortLE()); - position.setTime(convertTimestamp(buf.readUnsignedInt())); + position.setTime(convertTimestamp(buf.readUnsignedIntLE())); return position; } private Position parseTg2Report( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber) { Position position = new Position(getProtocolName()); position.setValid(true); position.set(Position.KEY_INDEX, sequenceNumber); position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedShort(); // report trigger + buf.readUnsignedShortLE(); // report trigger buf.readUnsignedByte(); // reserved buf.readUnsignedByte(); // assisted GPS age - position.setTime(convertTimestamp(buf.readUnsignedInt())); + position.setTime(convertTimestamp(buf.readUnsignedIntLE())); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - position.setAltitude(buf.readUnsignedShort()); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setAltitude(buf.readUnsignedShortLE()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - position.setSpeed(buf.readUnsignedShort() * 0.194384); - position.setCourse(buf.readUnsignedShort()); + position.setSpeed(buf.readUnsignedShortLE() * 0.194384); + position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - position.set("maximumSpeed", buf.readUnsignedShort()); - position.set("minimumSpeed", buf.readUnsignedShort()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + position.set("maximumSpeed", buf.readUnsignedShortLE()); + position.set("minimumSpeed", buf.readUnsignedShortLE()); - position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort()); // VSAUT1 voltage - position.set(Position.PREFIX_IO + 2, buf.readUnsignedShort()); // VSAUT2 voltage - position.set(Position.PREFIX_IO + 3, buf.readUnsignedShort()); // solar voltage + position.set(Position.PREFIX_IO + 1, buf.readUnsignedShortLE()); // VSAUT1 voltage + position.set(Position.PREFIX_IO + 2, buf.readUnsignedShortLE()); // VSAUT2 voltage + position.set(Position.PREFIX_IO + 3, buf.readUnsignedShortLE()); // solar voltage - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); return position; } private Position parsePositionReport( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber, long timestamp) { Position position = new Position(getProtocolName()); position.set(Position.KEY_INDEX, sequenceNumber); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(convertTimestamp(timestamp)); - position.setLatitude(buf.readMedium() * 0.00002); - position.setLongitude(buf.readMedium() * 0.00002); + position.setLatitude(buf.readMediumLE() * 0.00002); + position.setLongitude(buf.readMediumLE() * 0.00002); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); position.setCourse(buf.readUnsignedByte() * 2); @@ -173,15 +173,15 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { } private Position parsePositionReport2( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber, long timestamp) { Position position = new Position(getProtocolName()); position.set(Position.KEY_INDEX, sequenceNumber); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(convertTimestamp(timestamp)); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); buf.readUnsignedByte(); // report trigger @@ -191,13 +191,13 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { position.setValid((flags & 0x80) == 0x80 && (flags & 0x40) == 0x40); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); return position; } private Position parseSnapshot4( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber) { Position position = new Position(getProtocolName()); position.set(Position.KEY_INDEX, sequenceNumber); @@ -208,34 +208,34 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // GNSS fix quality buf.readUnsignedByte(); // GNSS assistance age - long flags = buf.readUnsignedInt(); + long flags = buf.readUnsignedIntLE(); position.setValid((flags & 0x0400) == 0x0400); - position.setTime(convertTimestamp(buf.readUnsignedInt())); + position.setTime(convertTimestamp(buf.readUnsignedIntLE())); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - position.setAltitude(buf.readUnsignedShort()); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setAltitude(buf.readUnsignedShortLE()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - position.setSpeed(buf.readUnsignedShort() * 0.194384); - position.setCourse(buf.readUnsignedShort() * 0.1); + position.setSpeed(buf.readUnsignedShortLE() * 0.194384); + position.setCourse(buf.readUnsignedShortLE() * 0.1); position.set("maximumSpeed", buf.readUnsignedByte()); position.set("minimumSpeed", buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); position.set(Position.PREFIX_IO + 1, buf.readUnsignedByte()); // supply voltage 1 position.set(Position.PREFIX_IO + 2, buf.readUnsignedByte()); // supply voltage 2 - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); return position; } private Position parseTrackingData( - DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) { + DeviceSession deviceSession, ByteBuf buf, int sequenceNumber, long timestamp) { Position position = new Position(getProtocolName()); position.set(Position.KEY_INDEX, sequenceNumber); @@ -247,17 +247,17 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { short flags = buf.readUnsignedByte(); position.setValid((flags & 0x01) == 0x01); - buf.readUnsignedShort(); // duration + buf.readUnsignedShortLE(); // duration - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); position.setCourse(buf.readUnsignedByte() * 2.0); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); return position; } @@ -266,22 +266,22 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // protocol version buf.readUnsignedByte(); // version id - int sequenceNumber = buf.readUnsignedShort(); - int messageId = buf.readUnsignedShort(); - buf.readUnsignedShort(); // length - int flags = buf.readUnsignedShort(); - buf.readUnsignedShort(); // checksum + int sequenceNumber = buf.readUnsignedShortLE(); + int messageId = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // length + int flags = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // checksum - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedIntLE())); if (deviceSession == null) { return null; } - long timestamp = buf.readUnsignedInt(); + long timestamp = buf.readUnsignedIntLE(); if ((flags & 0x1) == 0x0) { sendAcknowledgment(channel, sequenceNumber); diff --git a/src/org/traccar/protocol/NavisProtocol.java b/src/org/traccar/protocol/NavisProtocol.java index 771c9d61d..92b705517 100644 --- a/src/org/traccar/protocol/NavisProtocol.java +++ b/src/org/traccar/protocol/NavisProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class NavisProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(4 * 1024, 12, 2, 2, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4 * 1024, 12, 2, 2, 0, true)); pipeline.addLast("objectDecoder", new NavisProtocolDecoder(NavisProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java index 6881fb8ed..8da94b9aa 100644 --- a/src/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/org/traccar/protocol/NavisProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; @@ -75,23 +75,23 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { } } - private ParseResult parsePosition(DeviceSession deviceSession, ChannelBuffer buf) { + private ParseResult parsePosition(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); int format; if (buf.getUnsignedByte(buf.readerIndex()) == 0) { - format = buf.readUnsignedShort(); + format = buf.readUnsignedShortLE(); } else { format = buf.readUnsignedByte(); } position.set("format", format); - long index = buf.readUnsignedInt(); + long index = buf.readUnsignedIntLE(); position.set(Position.KEY_INDEX, index); - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); + position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); buf.skipBytes(6); // event time @@ -104,33 +104,33 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); if (isFormat(format, F10, F20, F30)) { - position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); } else if (isFormat(format, F40, F50, F51, F52)) { position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); } if (isFormat(format, F10, F20, F30, F40)) { - position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); } else if (isFormat(format, F50, F51, F52)) { position.set(Position.KEY_INPUT, buf.readUnsignedByte()); } - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE()); if (isFormat(format, F10, F20, F30)) { - position.set(Position.PREFIX_TEMP + 1, buf.readShort()); + position.set(Position.PREFIX_TEMP + 1, buf.readShortLE()); } if (isFormat(format, F10, F20, F50, F52)) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); } // Impulse counters if (isFormat(format, F20, F50, F51, F52)) { - buf.readUnsignedInt(); - buf.readUnsignedInt(); + buf.readUnsignedIntLE(); + buf.readUnsignedIntLE(); } if (isFormat(format, F20, F50, F51, F52)) { @@ -142,30 +142,30 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte() + 1, buf.readUnsignedByte()); position.setTime(dateBuilder.getDate()); - position.setLatitude(buf.readFloat() / Math.PI * 180); - position.setLongitude(buf.readFloat() / Math.PI * 180); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloat())); - position.setCourse(buf.readUnsignedShort()); + position.setLatitude(buf.readFloatLE() / Math.PI * 180); + position.setLongitude(buf.readFloatLE() / Math.PI * 180); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); + position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readFloat() * 1000); - position.set(Position.KEY_DISTANCE, buf.readFloat()); + position.set(Position.KEY_ODOMETER, buf.readFloatLE() * 1000); + position.set(Position.KEY_DISTANCE, buf.readFloatLE()); // Segment times - buf.readUnsignedShort(); - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); } // Other if (isFormat(format, F51, F52)) { - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); buf.readByte(); - buf.readUnsignedShort(); - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); buf.readByte(); - buf.readUnsignedShort(); - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); buf.readByte(); - buf.readUnsignedShort(); + buf.readUnsignedShortLE(); } // Four temperature sensors @@ -179,12 +179,12 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { return new ParseResult(index, position); } - private Object processSingle(DeviceSession deviceSession, Channel channel, ChannelBuffer buf) { + private Object processSingle(DeviceSession deviceSession, Channel channel, ByteBuf buf) { ParseResult result = parsePosition(deviceSession, buf); - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 8); - response.writeBytes(ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "*<T", StandardCharsets.US_ASCII)); - response.writeInt((int) result.getId()); + ByteBuf response = Unpooled.buffer(8); + response.writeCharSequence("*<T", StandardCharsets.US_ASCII); + response.writeIntLE((int) result.getId()); sendReply(channel, response); if (result.getPosition().getFixTime() == null) { @@ -194,7 +194,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { return result.getPosition(); } - private Object processArray(DeviceSession deviceSession, Channel channel, ChannelBuffer buf) { + private Object processArray(DeviceSession deviceSession, Channel channel, ByteBuf buf) { List<Position> positions = new LinkedList<>(); int count = buf.readUnsignedByte(); @@ -205,8 +205,8 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { } } - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 8); - response.writeBytes(ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "*<A", StandardCharsets.US_ASCII)); + ByteBuf response = Unpooled.buffer(8); + response.writeCharSequence("*<A", StandardCharsets.US_ASCII); response.writeByte(count); sendReply(channel, response); @@ -217,15 +217,15 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { return positions; } - private Object processHandshake(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Object processHandshake(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readByte(); // semicolon symbol if (getDeviceSession(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)) != null) { - sendReply(channel, ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "*<S", StandardCharsets.US_ASCII)); + sendReply(channel, Unpooled.copiedBuffer("*<S", StandardCharsets.US_ASCII)); } return null; } - private static short checksum(ChannelBuffer buf) { + private static short checksum(ByteBuf buf) { short sum = 0; for (int i = 0; i < buf.readableBytes(); i++) { sum ^= buf.getUnsignedByte(i); @@ -233,17 +233,17 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { return sum; } - private void sendReply(Channel channel, ChannelBuffer data) { - ChannelBuffer header = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 16); - header.writeBytes(ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, prefix, StandardCharsets.US_ASCII)); - header.writeInt((int) deviceUniqueId); - header.writeInt((int) serverId); - header.writeShort(data.readableBytes()); - header.writeByte(checksum(data)); - header.writeByte(checksum(header)); - + private void sendReply(Channel channel, ByteBuf data) { if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer(header, data)); + ByteBuf header = Unpooled.buffer(16); + header.writeCharSequence(prefix, StandardCharsets.US_ASCII); + header.writeIntLE((int) deviceUniqueId); + header.writeIntLE((int) serverId); + header.writeShortLE(data.readableBytes()); + header.writeByte(checksum(data)); + header.writeByte(checksum(header)); + + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(header, data), channel.remoteAddress())); } } @@ -251,13 +251,13 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; prefix = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); buf.skipBytes(prefix.length()); // prefix @NTC by default - serverId = buf.readUnsignedInt(); - deviceUniqueId = buf.readUnsignedInt(); - int length = buf.readUnsignedShort(); + serverId = buf.readUnsignedIntLE(); + deviceUniqueId = buf.readUnsignedIntLE(); + int length = buf.readUnsignedShortLE(); buf.skipBytes(2); // header and data XOR checksum if (length == 0) { diff --git a/src/org/traccar/protocol/NoranProtocol.java b/src/org/traccar/protocol/NoranProtocol.java index 7d3dc4852..9cae57b32 100644 --- a/src/org/traccar/protocol/NoranProtocol.java +++ b/src/org/traccar/protocol/NoranProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class NoranProtocol extends BaseProtocol { @@ -38,15 +36,13 @@ public class NoranProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new NoranProtocolEncoder()); pipeline.addLast("objectDecoder", new NoranProtocolDecoder(NoranProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/NoranProtocolDecoder.java b/src/org/traccar/protocol/NoranProtocolDecoder.java index e10332ece..65bd64384 100644 --- a/src/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/org/traccar/protocol/NoranProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -51,24 +51,22 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - buf.readUnsignedShort(); // length - int type = buf.readUnsignedShort(); + buf.readUnsignedShortLE(); // length + int type = buf.readUnsignedShortLE(); if (type == MSG_SHAKE_HAND && channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 13); - response.writeBytes( - ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "\r\n*KW", StandardCharsets.US_ASCII)); + ByteBuf response = Unpooled.buffer(13); + response.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII); response.writeByte(0); - response.writeShort(response.capacity()); - response.writeShort(MSG_SHAKE_HAND_RESPONSE); + response.writeShortLE(response.capacity()); + response.writeShortLE(MSG_SHAKE_HAND_RESPONSE); response.writeByte(1); // status - response.writeBytes( - ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "\r\n", StandardCharsets.US_ASCII)); + response.writeCharSequence("\r\n", StandardCharsets.US_ASCII); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else if (type == MSG_UPLOAD_POSITION || type == MSG_UPLOAD_POSITION_NEW || type == MSG_CONTROL_RESPONSE || type == MSG_ALARM) { @@ -83,8 +81,8 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); if (type == MSG_CONTROL_RESPONSE) { - buf.readUnsignedInt(); // GIS ip - buf.readUnsignedInt(); // GIS port + buf.readUnsignedIntLE(); // GIS ip + buf.readUnsignedIntLE(); // GIS port } position.setValid(BitUtil.check(buf.readUnsignedByte(), 0)); @@ -108,17 +106,17 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { } if (newFormat) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedInt())); - position.setCourse(buf.readFloat()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedIntLE())); + position.setCourse(buf.readFloatLE()); } else { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedShort()); + position.setCourse(buf.readUnsignedShortLE()); } - position.setLongitude(buf.readFloat()); - position.setLatitude(buf.readFloat()); + position.setLongitude(buf.readFloatLE()); + position.setLatitude(buf.readFloatLE()); if (!newFormat) { - long timeValue = buf.readUnsignedInt(); + long timeValue = buf.readUnsignedIntLE(); DateBuilder dateBuilder = new DateBuilder() .setYear((int) BitUtil.from(timeValue, 26)) .setMonth((int) BitUtil.between(timeValue, 22, 26)) @@ -129,11 +127,11 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { position.setTime(dateBuilder.getDate()); } - ChannelBuffer rawId; + ByteBuf rawId; if (newFormat) { - rawId = buf.readBytes(12); + rawId = buf.readSlice(12); } else { - rawId = buf.readBytes(11); + rawId = buf.readSlice(11); } String id = rawId.toString(StandardCharsets.US_ASCII).replaceAll("[^\\p{Print}]", ""); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); @@ -144,7 +142,7 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { if (newFormat) { DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); - position.setTime(dateFormat.parse(buf.readBytes(17).toString(StandardCharsets.US_ASCII))); + position.setTime(dateFormat.parse(buf.readSlice(17).toString(StandardCharsets.US_ASCII))); buf.readByte(); } @@ -152,8 +150,8 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_IO + 1, buf.readUnsignedByte()); position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); } else if (type == MSG_UPLOAD_POSITION_NEW) { - position.set(Position.PREFIX_TEMP + 1, buf.readShort()); - position.set(Position.KEY_ODOMETER, buf.readFloat()); + position.set(Position.PREFIX_TEMP + 1, buf.readShortLE()); + position.set(Position.KEY_ODOMETER, buf.readFloatLE()); } return position; diff --git a/src/org/traccar/protocol/NoranProtocolEncoder.java b/src/org/traccar/protocol/NoranProtocolEncoder.java index 25b510a73..53b0c54ba 100644 --- a/src/org/traccar/protocol/NoranProtocolEncoder.java +++ b/src/org/traccar/protocol/NoranProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,32 +15,29 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; public class NoranProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(String content) { + private ByteBuf encodeContent(String content) { - ChannelBuffer buf = ChannelBuffers.buffer(ByteOrder.LITTLE_ENDIAN, 12 + 56); + ByteBuf buf = Unpooled.buffer(12 + 56); - buf.writeBytes( - ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "\r\n*KW", StandardCharsets.US_ASCII)); + buf.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII); buf.writeByte(0); - buf.writeShort(buf.capacity()); - buf.writeShort(NoranProtocolDecoder.MSG_CONTROL); + buf.writeShortLE(buf.capacity()); + buf.writeShortLE(NoranProtocolDecoder.MSG_CONTROL); buf.writeInt(0); // gis ip - buf.writeShort(0); // gis port + buf.writeShortLE(0); // gis port buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); buf.writerIndex(buf.writerIndex() + 50 - content.length()); - buf.writeBytes( - ChannelBuffers.copiedBuffer(ByteOrder.LITTLE_ENDIAN, "\r\n", StandardCharsets.US_ASCII)); + buf.writeCharSequence("\r\n", StandardCharsets.US_ASCII); return buf; } diff --git a/src/org/traccar/protocol/NvsFrameDecoder.java b/src/org/traccar/protocol/NvsFrameDecoder.java index 598bb1e4c..e93a58cf6 100644 --- a/src/org/traccar/protocol/NvsFrameDecoder.java +++ b/src/org/traccar/protocol/NvsFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,18 +15,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class NvsFrameDecoder extends FrameDecoder { +public class NvsFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 4 + 2) { return null; @@ -40,7 +38,7 @@ public class NvsFrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/NvsProtocol.java b/src/org/traccar/protocol/NvsProtocol.java index fdcb2bbcf..aaf447120 100644 --- a/src/org/traccar/protocol/NvsProtocol.java +++ b/src/org/traccar/protocol/NvsProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class NvsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new NvsFrameDecoder()); pipeline.addLast("objectDecoder", new NvsProtocolDecoder(NvsProtocol.this)); } diff --git a/src/org/traccar/protocol/NvsProtocolDecoder.java b/src/org/traccar/protocol/NvsProtocolDecoder.java index db8347d3c..46909ff0c 100644 --- a/src/org/traccar/protocol/NvsProtocolDecoder.java +++ b/src/org/traccar/protocol/NvsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -35,9 +36,10 @@ public class NvsProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void sendResponse(Channel channel, String response) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String response) { if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer(response, StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer(response, StandardCharsets.US_ASCII), remoteAddress)); } } @@ -45,7 +47,7 @@ public class NvsProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getUnsignedByte(buf.readerIndex()) == 0) { @@ -55,9 +57,9 @@ public class NvsProtocolDecoder extends BaseProtocolDecoder { String imei = buf.toString(buf.readerIndex(), 15, StandardCharsets.US_ASCII); if (getDeviceSession(channel, remoteAddress, imei) != null) { - sendResponse(channel, "OK"); + sendResponse(channel, remoteAddress, "OK"); } else { - sendResponse(channel, "NO01"); + sendResponse(channel, remoteAddress, "NO01"); } } else { diff --git a/src/org/traccar/protocol/ObdDongleProtocol.java b/src/org/traccar/protocol/ObdDongleProtocol.java index 6547a31ab..5f50b16ae 100644 --- a/src/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/org/traccar/protocol/ObdDongleProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class ObdDongleProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); pipeline.addLast("objectDecoder", new ObdDongleProtocolDecoder(ObdDongleProtocol.this)); } diff --git a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/org/traccar/protocol/ObdDongleProtocolDecoder.java index 5310c90fd..2f96bbac5 100644 --- a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java +++ b/src/org/traccar/protocol/ObdDongleProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -42,18 +43,19 @@ public class ObdDongleProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TYPE_PINGRESP = 0x0D; public static final int MSG_TYPE_DISCONNECT = 0x0E; - private static void sendResponse(Channel channel, int type, int index, String imei, ChannelBuffer content) { + private static void sendResponse(Channel channel, int type, int index, String imei, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeShort(0x5555); // header response.writeShort(index); response.writeBytes(imei.getBytes(StandardCharsets.US_ASCII)); response.writeByte(type); response.writeShort(content.readableBytes()); response.writeBytes(content); + content.release(); response.writeByte(0); // checksum response.writeShort(0xAAAA); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -61,12 +63,12 @@ public class ObdDongleProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header int index = buf.readUnsignedShort(); - String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; @@ -78,7 +80,7 @@ public class ObdDongleProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_TYPE_CONNECT) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(1); response.writeShort(0); response.writeInt(0); @@ -112,7 +114,7 @@ public class ObdDongleProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromMph(BitUtil.from(speedCourse, 10) * 0.1)); position.setCourse(BitUtil.to(speedCourse, 10)); - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(typeMajor); response.writeByte(typeMinor); sendResponse(channel, MSG_TYPE_PUBACK, index, imei, response); diff --git a/src/org/traccar/protocol/OigoProtocol.java b/src/org/traccar/protocol/OigoProtocol.java index 4b6ad0dd0..b4f2b4163 100644 --- a/src/org/traccar/protocol/OigoProtocol.java +++ b/src/org/traccar/protocol/OigoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class OigoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new OigoProtocolDecoder(OigoProtocol.this)); } }); diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java index 2874d0455..fe356f7cf 100644 --- a/src/org/traccar/protocol/OigoProtocolDecoder.java +++ b/src/org/traccar/protocol/OigoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; @@ -39,7 +41,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_ACKNOWLEDGEMENT = 0xE0; - private Position decodeArMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Position decodeArMessage(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.skipBytes(1); // header buf.readUnsignedShort(); // length @@ -51,12 +53,12 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession; switch (BitUtil.to(tag, 3)) { case 0: - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); deviceSession = getDeviceSession(channel, remoteAddress, imei); break; case 1: buf.skipBytes(1); - String meid = buf.readBytes(14).toString(StandardCharsets.US_ASCII); + String meid = buf.readSlice(14).toString(StandardCharsets.US_ASCII); deviceSession = getDeviceSession(channel, remoteAddress, meid); break; default: @@ -159,7 +161,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { return negative ? -degrees : degrees; } - private Position decodeMgMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Position decodeMgMessage(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedByte(); // tag int flags = buf.getUnsignedByte(buf.readerIndex()); @@ -169,7 +171,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // flags deviceSession = getDeviceSession(channel, remoteAddress); } else { - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); deviceSession = getDeviceSession(channel, remoteAddress, imei); } @@ -211,11 +213,11 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, (long) (buf.readUnsignedInt() * 1609.34)); if (channel != null && BitUtil.check(flags, 7)) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(MSG_ACKNOWLEDGEMENT); response.writeByte(index); response.writeByte(0x00); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return position; @@ -225,7 +227,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getUnsignedByte(buf.readerIndex()) == 0x7e) { return decodeArMessage(channel, remoteAddress, buf); diff --git a/src/org/traccar/protocol/OkoProtocol.java b/src/org/traccar/protocol/OkoProtocol.java index 0b38741e5..21f06cca0 100644 --- a/src/org/traccar/protocol/OkoProtocol.java +++ b/src/org/traccar/protocol/OkoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class OkoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '}')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new OkoProtocolDecoder(OkoProtocol.this)); diff --git a/src/org/traccar/protocol/OkoProtocolDecoder.java b/src/org/traccar/protocol/OkoProtocolDecoder.java index 0ebe63ca3..0318c30c7 100644 --- a/src/org/traccar/protocol/OkoProtocolDecoder.java +++ b/src/org/traccar/protocol/OkoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/OpenGtsProtocol.java b/src/org/traccar/protocol/OpenGtsProtocol.java index a0246ba1b..afc0b0c60 100644 --- a/src/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/org/traccar/protocol/OpenGtsProtocol.java @@ -15,11 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,11 +32,12 @@ public class OpenGtsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(16384)); pipeline.addLast("objectDecoder", new OpenGtsProtocolDecoder(OpenGtsProtocol.this)); } }); diff --git a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java index ba8f434d8..b61426085 100644 --- a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java +++ b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java @@ -15,10 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.QueryStringDecoder; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -55,9 +55,9 @@ public class OpenGtsProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.getUri()); - Map<String, List<String>> params = decoder.getParameters(); + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); + Map<String, List<String>> params = decoder.parameters(); Position position = new Position(); position.setProtocol(getProtocolName()); diff --git a/src/org/traccar/protocol/OrionFrameDecoder.java b/src/org/traccar/protocol/OrionFrameDecoder.java index f7371747a..948806609 100644 --- a/src/org/traccar/protocol/OrionFrameDecoder.java +++ b/src/org/traccar/protocol/OrionFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,18 +15,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class OrionFrameDecoder extends FrameDecoder { +public class OrionFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { int length = 6; @@ -51,14 +49,14 @@ public class OrionFrameDecoder extends FrameDecoder { } if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } else if (type == OrionProtocolDecoder.MSG_SYSLOG && buf.readableBytes() >= length + 12) { - length += buf.getUnsignedShort(buf.readerIndex() + 8); + length += buf.getUnsignedShortLE(buf.readerIndex() + 8); if (buf.readableBytes() >= length) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } } diff --git a/src/org/traccar/protocol/OrionProtocol.java b/src/org/traccar/protocol/OrionProtocol.java index f4bfef985..ba7044cce 100644 --- a/src/org/traccar/protocol/OrionProtocol.java +++ b/src/org/traccar/protocol/OrionProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class OrionProtocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class OrionProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new OrionFrameDecoder()); pipeline.addLast("objectDecoder", new OrionProtocolDecoder(OrionProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/OrionProtocolDecoder.java b/src/org/traccar/protocol/OrionProtocolDecoder.java index ada864fba..bbc509bec 100644 --- a/src/org/traccar/protocol/OrionProtocolDecoder.java +++ b/src/org/traccar/protocol/OrionProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; @@ -36,13 +37,13 @@ public class OrionProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_USERLOG = 0; public static final int MSG_SYSLOG = 3; - private static void sendResponse(Channel channel, ChannelBuffer buf) { + private static void sendResponse(Channel channel, ByteBuf buf) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(4); + ByteBuf response = Unpooled.buffer(4); response.writeByte('*'); response.writeShort(buf.getUnsignedShort(buf.writerIndex() - 2)); response.writeByte(buf.getUnsignedByte(buf.writerIndex() - 3)); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -56,7 +57,7 @@ public class OrionProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte() & 0x0f; @@ -84,13 +85,13 @@ public class OrionProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, buf.readUnsignedByte()); buf.readUnsignedByte(); // length - position.set(Position.KEY_FLAGS, buf.readUnsignedShort()); + position.set(Position.KEY_FLAGS, buf.readUnsignedShortLE()); - position.setLatitude(convertCoordinate(buf.readInt())); - position.setLongitude(convertCoordinate(buf.readInt())); - position.setAltitude(buf.readShort() / 10.0); - position.setCourse(buf.readUnsignedShort()); - position.setSpeed(buf.readUnsignedShort() * 0.0539957); + position.setLatitude(convertCoordinate(buf.readIntLE())); + position.setLongitude(convertCoordinate(buf.readIntLE())); + position.setAltitude(buf.readShortLE() / 10.0); + position.setCourse(buf.readUnsignedShortLE()); + position.setSpeed(buf.readUnsignedShortLE() * 0.0539957); DateBuilder dateBuilder = new DateBuilder() .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) diff --git a/src/org/traccar/protocol/OsmAndProtocol.java b/src/org/traccar/protocol/OsmAndProtocol.java index 785f4bd75..a199f067a 100644 --- a/src/org/traccar/protocol/OsmAndProtocol.java +++ b/src/org/traccar/protocol/OsmAndProtocol.java @@ -15,11 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,11 +32,12 @@ public class OsmAndProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(16384)); pipeline.addLast("objectDecoder", new OsmAndProtocolDecoder(OsmAndProtocol.this)); } }); diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 03abdd588..c75e9519c 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,10 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.QueryStringDecoder; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; import org.joda.time.format.ISODateTimeFormat; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; @@ -42,15 +42,14 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { } @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.getUri()); - Map<String, List<String>> params = decoder.getParameters(); + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); + Map<String, List<String>> params = decoder.parameters(); if (params.isEmpty()) { - decoder = new QueryStringDecoder(request.getContent().toString(StandardCharsets.US_ASCII), false); - params = decoder.getParameters(); + decoder = new QueryStringDecoder(request.content().toString(StandardCharsets.US_ASCII), false); + params = decoder.parameters(); } Position position = new Position(getProtocolName()); diff --git a/src/org/traccar/protocol/OwnTracksProtocol.java b/src/org/traccar/protocol/OwnTracksProtocol.java index c4a6ab163..275bb739a 100644 --- a/src/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/org/traccar/protocol/OwnTracksProtocol.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Jan-Piet Mens (jpmens@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -16,11 +16,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,11 +33,12 @@ public class OwnTracksProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(16384)); pipeline.addLast("objectDecoder", new OwnTracksProtocolDecoder(OwnTracksProtocol.this)); } }); diff --git a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java index 120995dfb..00a63d712 100644 --- a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Jan-Piet Mens (jpmens@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -16,9 +16,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.UnitsConverter; @@ -41,9 +41,9 @@ public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; + FullHttpRequest request = (FullHttpRequest) msg; JsonObject root = Json.createReader( - new StringReader(request.getContent().toString(StandardCharsets.US_ASCII))).readObject(); + new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); if (!root.containsKey("_type") || !root.getString("_type").equals("location")) { sendResponse(channel, HttpResponseStatus.OK); @@ -98,4 +98,5 @@ public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { sendResponse(channel, HttpResponseStatus.OK); return position; } + } diff --git a/src/org/traccar/protocol/PathAwayProtocol.java b/src/org/traccar/protocol/PathAwayProtocol.java index a41692750..7cb5a3fca 100644 --- a/src/org/traccar/protocol/PathAwayProtocol.java +++ b/src/org/traccar/protocol/PathAwayProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,11 +32,12 @@ public class PathAwayProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(16384)); pipeline.addLast("objectDecoder", new PathAwayProtocolDecoder(PathAwayProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/org/traccar/protocol/PathAwayProtocolDecoder.java index 845a5e892..40e68a5d2 100644 --- a/src/org/traccar/protocol/PathAwayProtocolDecoder.java +++ b/src/org/traccar/protocol/PathAwayProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,16 +15,17 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFutureListener; -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.QueryStringDecoder; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; @@ -58,16 +59,16 @@ public class PathAwayProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.getUri()); + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, decoder.getParameters().get("UserName").get(0)); + channel, remoteAddress, decoder.parameters().get("UserName").get(0)); if (deviceSession == null) { return null; } - Parser parser = new Parser(PATTERN, decoder.getParameters().get("LOC").get(0)); + Parser parser = new Parser(PATTERN, decoder.parameters().get("LOC").get(0)); if (!parser.matches()) { return null; } @@ -85,8 +86,8 @@ public class PathAwayProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble(0)); if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - channel.write(response).addListener(ChannelFutureListener.CLOSE); + FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)).addListener(ChannelFutureListener.CLOSE); } return position; diff --git a/src/org/traccar/protocol/PiligrimProtocol.java b/src/org/traccar/protocol/PiligrimProtocol.java index a2960f762..ff602d366 100644 --- a/src/org/traccar/protocol/PiligrimProtocol.java +++ b/src/org/traccar/protocol/PiligrimProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,12 +32,12 @@ public class PiligrimProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(16384)); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(16384)); pipeline.addLast("objectDecoder", new PiligrimProtocolDecoder(PiligrimProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/org/traccar/protocol/PiligrimProtocolDecoder.java index f2ec16c59..a1850df54 100644 --- a/src/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,23 +15,23 @@ */ 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.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.QueryStringDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; @@ -44,11 +44,10 @@ public class PiligrimProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, String message) { if (channel != null) { - HttpResponse response = new DefaultHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - response.setContent(ChannelBuffers.copiedBuffer( - ByteOrder.BIG_ENDIAN, message, StandardCharsets.US_ASCII)); - channel.write(response); + FullHttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + Unpooled.copiedBuffer(message, StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -60,8 +59,8 @@ public class PiligrimProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; - String uri = request.getUri(); + FullHttpRequest request = (FullHttpRequest) msg; + String uri = request.uri(); if (uri.startsWith("/config")) { @@ -79,15 +78,15 @@ public class PiligrimProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, "BINGPS: OK"); - QueryStringDecoder decoder = new QueryStringDecoder(request.getUri()); + QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, decoder.getParameters().get("imei").get(0)); + channel, remoteAddress, decoder.parameters().get("imei").get(0)); if (deviceSession == null) { return null; } List<Position> positions = new LinkedList<>(); - ChannelBuffer buf = request.getContent(); + ByteBuf buf = request.content(); while (buf.readableBytes() > 2) { diff --git a/src/org/traccar/protocol/PretraceProtocol.java b/src/org/traccar/protocol/PretraceProtocol.java index 8f0a22851..811c387f6 100644 --- a/src/org/traccar/protocol/PretraceProtocol.java +++ b/src/org/traccar/protocol/PretraceProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,13 +15,13 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.model.Command; import java.util.List; @@ -29,16 +29,20 @@ public class PretraceProtocol extends BaseProtocol { public PretraceProtocol() { super("pretrace"); + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_PERIODIC); } @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectEncoder", new PretraceProtocolEncoder()); pipeline.addLast("objectDecoder", new PretraceProtocolDecoder(PretraceProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PretraceProtocolDecoder.java b/src/org/traccar/protocol/PretraceProtocolDecoder.java index 24d707a1c..e4306a429 100644 --- a/src/org/traccar/protocol/PretraceProtocolDecoder.java +++ b/src/org/traccar/protocol/PretraceProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/PretraceProtocolEncoder.java b/src/org/traccar/protocol/PretraceProtocolEncoder.java new file mode 100644 index 000000000..e8e2f66c7 --- /dev/null +++ b/src/org/traccar/protocol/PretraceProtocolEncoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocolEncoder; +import org.traccar.Context; +import org.traccar.helper.Checksum; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +public class PretraceProtocolEncoder extends BaseProtocolEncoder { + + private String formatCommand(String uniqueId, String data) { + String content = uniqueId + data; + return String.format("(%s^%02X)", content, Checksum.xor(content)); + } + + @Override + protected Object encodeCommand(Command command) { + + String uniqueId = Context.getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC: + return formatCommand( + uniqueId, String.format("D221%1$d,%1$d,,", command.getInteger(Command.KEY_FREQUENCY))); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + return null; + } + } + +} diff --git a/src/org/traccar/protocol/PricolProtocol.java b/src/org/traccar/protocol/PricolProtocol.java index 0005dc3c1..ca52e2734 100644 --- a/src/org/traccar/protocol/PricolProtocol.java +++ b/src/org/traccar/protocol/PricolProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder; +import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,16 +30,16 @@ public class PricolProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new FixedLengthFrameDecoder(64)); pipeline.addLast("objectDecoder", new PricolProtocolDecoder(PricolProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new PricolProtocolDecoder(PricolProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PricolProtocolDecoder.java b/src/org/traccar/protocol/PricolProtocolDecoder.java index 577665dcc..b76e5f27f 100644 --- a/src/org/traccar/protocol/PricolProtocolDecoder.java +++ b/src/org/traccar/protocol/PricolProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -37,12 +38,12 @@ public class PricolProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); + channel, remoteAddress, buf.readSlice(7).toString(StandardCharsets.US_ASCII)); if (deviceSession == null) { return null; } @@ -86,7 +87,8 @@ public class PricolProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, buf.readUnsignedShort()); if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer("ACK", StandardCharsets.US_ASCII), remoteAddress); + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer("ACK", StandardCharsets.US_ASCII), remoteAddress)); } return position; diff --git a/src/org/traccar/protocol/ProgressProtocol.java b/src/org/traccar/protocol/ProgressProtocol.java index 6e2093346..22fdfbd48 100644 --- a/src/org/traccar/protocol/ProgressProtocol.java +++ b/src/org/traccar/protocol/ProgressProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class ProgressProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, 4, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast("objectDecoder", new ProgressProtocolDecoder(ProgressProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/ProgressProtocolDecoder.java b/src/org/traccar/protocol/ProgressProtocolDecoder.java index d85b6acb3..dca0e649e 100644 --- a/src/org/traccar/protocol/ProgressProtocolDecoder.java +++ b/src/org/traccar/protocol/ProgressProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,16 +15,17 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; @@ -53,12 +54,12 @@ public class ProgressProtocolDecoder extends BaseProtocolDecoder { if (lastIndex == 0) { lastIndex = newIndex; } else if (newIndex > lastIndex) { - ChannelBuffer request = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 12); - request.writeShort(MSG_LOG_SYNC); - request.writeShort(4); - request.writeInt((int) lastIndex); - request.writeInt(0); - channel.write(request); + ByteBuf request = Unpooled.buffer(12); + request.writeShortLE(MSG_LOG_SYNC); + request.writeShortLE(4); + request.writeIntLE((int) lastIndex); + request.writeIntLE(0); + channel.writeAndFlush(new NetworkMessage(request, channel.remoteAddress())); } } @@ -66,19 +67,19 @@ public class ProgressProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; - int type = buf.readUnsignedShort(); - buf.readUnsignedShort(); // length + ByteBuf buf = (ByteBuf) msg; + int type = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // length if (type == MSG_IDENT || type == MSG_IDENT_FULL) { - buf.readUnsignedInt(); // id - int length = buf.readUnsignedShort(); + buf.readUnsignedIntLE(); // id + int length = buf.readUnsignedShortLE(); buf.skipBytes(length); - length = buf.readUnsignedShort(); + length = buf.readUnsignedShortLE(); buf.skipBytes(length); - length = buf.readUnsignedShort(); - String imei = buf.readBytes(length).toString(StandardCharsets.US_ASCII); + length = buf.readUnsignedShortLE(); + String imei = buf.readSlice(length).toString(StandardCharsets.US_ASCII); getDeviceSession(channel, remoteAddress, imei); } else if (type == MSG_POINT || type == MSG_ALARM || type == MSG_LOGMSG) { @@ -92,7 +93,7 @@ public class ProgressProtocolDecoder extends BaseProtocolDecoder { int recordCount = 1; if (type == MSG_LOGMSG) { - recordCount = buf.readUnsignedShort(); + recordCount = buf.readUnsignedShortLE(); } for (int j = 0; j < recordCount; j++) { @@ -101,61 +102,60 @@ public class ProgressProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_LOGMSG) { position.set(Position.KEY_ARCHIVE, true); - int subtype = buf.readUnsignedShort(); + int subtype = buf.readUnsignedShortLE(); if (subtype == MSG_ALARM) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - if (buf.readUnsignedShort() > buf.readableBytes()) { + if (buf.readUnsignedShortLE() > buf.readableBytes()) { lastIndex += 1; break; // workaround for device bug } - lastIndex = buf.readUnsignedInt(); + lastIndex = buf.readUnsignedIntLE(); position.set(Position.KEY_INDEX, lastIndex); } else { - newIndex = buf.readUnsignedInt(); + newIndex = buf.readUnsignedIntLE(); } - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.setLatitude(buf.readInt() * 180.0 / 0x7FFFFFFF); - position.setLongitude(buf.readInt() * 180.0 / 0x7FFFFFFF); - position.setSpeed(buf.readUnsignedInt() * 0.01); - position.setCourse(buf.readUnsignedShort() * 0.01); - position.setAltitude(buf.readUnsignedShort() * 0.01); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLatitude(buf.readIntLE() * 180.0 / 0x7FFFFFFF); + position.setLongitude(buf.readIntLE() * 180.0 / 0x7FFFFFFF); + position.setSpeed(buf.readUnsignedIntLE() * 0.01); + position.setCourse(buf.readUnsignedShortLE() * 0.01); + position.setAltitude(buf.readUnsignedShortLE() * 0.01); int satellites = buf.readUnsignedByte(); position.setValid(satellites >= 3); position.set(Position.KEY_SATELLITES, satellites); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - long extraFlags = buf.readLong(); + long extraFlags = buf.readLongLE(); if (BitUtil.check(extraFlags, 0)) { - int count = buf.readUnsignedShort(); + int count = buf.readUnsignedShortLE(); for (int i = 1; i <= count; i++) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE()); } } if (BitUtil.check(extraFlags, 1)) { - int size = buf.readUnsignedShort(); + int size = buf.readUnsignedShortLE(); position.set("can", buf.toString(buf.readerIndex(), size, StandardCharsets.US_ASCII)); buf.skipBytes(size); } if (BitUtil.check(extraFlags, 2)) { - position.set("passenger", - ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedShort()))); + position.set("passenger", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedShortLE()))); } if (type == MSG_ALARM) { position.set(Position.KEY_ALARM, true); byte[] response = {(byte) 0xC9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - channel.write(ChannelBuffers.wrappedBuffer(response)); + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); } - buf.readUnsignedInt(); // crc + buf.readUnsignedIntLE(); // crc positions.add(position); } diff --git a/src/org/traccar/protocol/Pt3000Protocol.java b/src/org/traccar/protocol/Pt3000Protocol.java index 9c9da3301..03cc493d9 100644 --- a/src/org/traccar/protocol/Pt3000Protocol.java +++ b/src/org/traccar/protocol/Pt3000Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Pt3000Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/org/traccar/protocol/Pt3000ProtocolDecoder.java index f4540afe8..8e9d99d14 100644 --- a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt3000ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/Pt502FrameDecoder.java b/src/org/traccar/protocol/Pt502FrameDecoder.java index 252c8dd02..316cd987f 100644 --- a/src/org/traccar/protocol/Pt502FrameDecoder.java +++ b/src/org/traccar/protocol/Pt502FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,39 +15,56 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class Pt502FrameDecoder extends FrameDecoder { +import java.nio.charset.StandardCharsets; + +public class Pt502FrameDecoder extends BaseFrameDecoder { private static final int BINARY_HEADER = 5; @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - if (buf.readableBytes() < BINARY_HEADER) { + if (buf.readableBytes() < 10) { return null; } - if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.skipBytes(BINARY_HEADER); - } + if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf + && buf.toString(buf.readerIndex() + BINARY_HEADER, 4, StandardCharsets.US_ASCII).equals("$PHD")) { - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\r'); - if (index < 0) { - index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\n'); - } + int length = buf.getUnsignedShortLE(buf.readerIndex() + 3); + if (buf.readableBytes() >= length) { + buf.skipBytes(BINARY_HEADER); + ByteBuf result = buf.readRetainedSlice(length - BINARY_HEADER - 2); + buf.skipBytes(2); // line break + return result; + } + + } else { - if (index > 0) { - ChannelBuffer result = buf.readBytes(index - buf.readerIndex()); - while (buf.readable() - && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) { - buf.skipBytes(1); + if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { + buf.skipBytes(BINARY_HEADER); } - return result; + + int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\r'); + if (index < 0) { + index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\n'); + } + + if (index > 0) { + ByteBuf result = buf.readRetainedSlice(index - buf.readerIndex()); + while (buf.isReadable() + && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) { + buf.skipBytes(1); + } + return result; + } + } return null; diff --git a/src/org/traccar/protocol/Pt502Protocol.java b/src/org/traccar/protocol/Pt502Protocol.java index 0116422c2..fe8a0bb6c 100644 --- a/src/org/traccar/protocol/Pt502Protocol.java +++ b/src/org/traccar/protocol/Pt502Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,15 +15,12 @@ */ 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 io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; -import java.nio.ByteOrder; import java.util.List; public class Pt502Protocol extends BaseProtocol { @@ -40,18 +37,15 @@ public class Pt502Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Pt502FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Pt502ProtocolEncoder()); pipeline.addLast("objectDecoder", new Pt502ProtocolDecoder(Pt502Protocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java index bc7647744..e0aea693a 100644 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -1,5 +1,5 @@ /*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
* Copyright 2012 Luis Parada (luis.parada@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,22 +16,27 @@ */
package org.traccar.protocol;
-import org.jboss.netty.channel.Channel;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.Context;
import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;
public class Pt502ProtocolDecoder extends BaseProtocolDecoder {
private static final int MAX_CHUNK_SIZE = 960;
- private byte[] photo;
+ private ByteBuf photo;
public Pt502ProtocolDecoder(Pt502Protocol protocol) {
super(protocol);
@@ -85,25 +90,15 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { }
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodePosition(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN, (String) msg);
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
Position position = new Position(getProtocolName());
-
- String type = parser.next();
-
- if (type.startsWith("PHO") && channel != null) {
- photo = new byte[Integer.parseInt(type.substring(3))];
- channel.write("#PHD0," + Math.min(photo.length, MAX_CHUNK_SIZE) + "\r\n");
- }
-
- position.set(Position.KEY_ALARM, decodeAlarm(type));
+ position.set(Position.KEY_ALARM, decodeAlarm(parser.next()));
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -146,4 +141,71 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { return position;
}
+ private void requestPhotoFragment(Channel channel) {
+ if (channel != null) {
+ int offset = photo.writerIndex();
+ int size = Math.min(photo.writableBytes(), MAX_CHUNK_SIZE);
+ channel.writeAndFlush(new NetworkMessage("#PHD" + offset + "," + size + "\r\n", channel.remoteAddress()));
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ int typeEndIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
+ String type = buf.toString(buf.readerIndex(), typeEndIndex - buf.readerIndex(), StandardCharsets.US_ASCII);
+
+ if (type.startsWith("$PHD")) {
+
+ int dataIndex = buf.indexOf(typeEndIndex + 1, buf.writerIndex(), (byte) ',') + 1;
+ buf.readerIndex(dataIndex);
+
+ if (photo != null) {
+
+ photo.writeBytes(buf.readSlice(buf.readableBytes()));
+
+ if (photo.writableBytes() > 0) {
+
+ requestPhotoFragment(channel);
+
+ } else {
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg"));
+ photo.release();
+ photo = null;
+
+ return position;
+
+ }
+
+ }
+
+ } else {
+
+ if (type.startsWith("$PHO")) {
+ int size = Integer.parseInt(type.split("-")[0].substring(4));
+ if (size > 0) {
+ photo = Unpooled.buffer(size);
+ requestPhotoFragment(channel);
+ }
+ }
+
+ return decodePosition(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII));
+
+ }
+
+ return null;
+ }
+
}
diff --git a/src/org/traccar/protocol/Pt60Protocol.java b/src/org/traccar/protocol/Pt60Protocol.java new file mode 100644 index 000000000..6c03f209e --- /dev/null +++ b/src/org/traccar/protocol/Pt60Protocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class Pt60Protocol extends BaseProtocol { + + public Pt60Protocol() { + super("pt60"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "@R#@")); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new Pt60ProtocolDecoder(Pt60Protocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/org/traccar/protocol/Pt60ProtocolDecoder.java new file mode 100644 index 000000000..63dd3c90b --- /dev/null +++ b/src/org/traccar/protocol/Pt60ProtocolDecoder.java @@ -0,0 +1,120 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Pattern; + +public class Pt60ProtocolDecoder extends BaseProtocolDecoder { + + public Pt60ProtocolDecoder(Pt60Protocol protocol) { + super(protocol); + } + + public static final int MSG_TRACK = 6; + public static final int MSG_STEP_COUNT = 13; + public static final int MSG_HEART_RATE = 14; + + private static final Pattern PATTERN = new PatternBuilder() + .text("@G#@,") // header + .number("Vdd,") // protocol version + .number("(d+),") // type + .number("(d+),") // imei + .number("(d+),") // imsi + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .expression("(.*)") // data + .compile(); + + private void sendResponse(Channel channel, SocketAddress remoteAddress) { + if (channel != null) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + channel.writeAndFlush(new NetworkMessage( + "@G#@,V01,38," + dateFormat.format(new Date()) + ",@R#@", remoteAddress)); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + sendResponse(channel, remoteAddress); + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + int type = parser.nextInt(); + + if (type != MSG_TRACK && type != MSG_STEP_COUNT && type != MSG_HEART_RATE) { + return null; + } + + Position position = new Position(getProtocolName()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), parser.next()); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + position.setDeviceTime(parser.nextDateTime()); + + String[] values = parser.next().split(","); + + if (type == MSG_TRACK) { + + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + + String[] coordinates = values[0].split(";"); + position.setLatitude(Double.parseDouble(coordinates[0])); + position.setLongitude(Double.parseDouble(coordinates[1])); + + } else { + + getLastLocation(position, position.getDeviceTime()); + + switch (type) { + case MSG_STEP_COUNT: + position.set(Position.KEY_STEPS, Integer.parseInt(values[0])); + break; + case MSG_HEART_RATE: + position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[0])); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[1])); + break; + default: + break; + } + + } + + return position; + } + +} diff --git a/src/org/traccar/protocol/RaveonProtocol.java b/src/org/traccar/protocol/RaveonProtocol.java index e4e100e0b..3dfca17fb 100644 --- a/src/org/traccar/protocol/RaveonProtocol.java +++ b/src/org/traccar/protocol/RaveonProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class RaveonProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/RaveonProtocolDecoder.java b/src/org/traccar/protocol/RaveonProtocolDecoder.java index ac52493ad..099c188ac 100644 --- a/src/org/traccar/protocol/RaveonProtocolDecoder.java +++ b/src/org/traccar/protocol/RaveonProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/RecodaProtocol.java b/src/org/traccar/protocol/RecodaProtocol.java index daf167fd9..ac8f772b6 100644 --- a/src/org/traccar/protocol/RecodaProtocol.java +++ b/src/org/traccar/protocol/RecodaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class RecodaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 4, 4, -8, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); pipeline.addLast("objectDecoder", new RecodaProtocolDecoder(RecodaProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/RecodaProtocolDecoder.java b/src/org/traccar/protocol/RecodaProtocolDecoder.java index 7bd4d3dae..eef1cb5af 100644 --- a/src/org/traccar/protocol/RecodaProtocolDecoder.java +++ b/src/org/traccar/protocol/RecodaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -43,19 +43,19 @@ public class RecodaProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - int type = buf.readInt(); - buf.readUnsignedInt(); // length + int type = buf.readIntLE(); + buf.readUnsignedIntLE(); // length if (type != MSG_HEARTBEAT) { - buf.readUnsignedShort(); // version - buf.readUnsignedShort(); // index + buf.readUnsignedShortLE(); // version + buf.readUnsignedShortLE(); // index } if (type == MSG_SIGNAL_LINK_REGISTRATION) { - getDeviceSession(channel, remoteAddress, buf.readBytes(12).toString(StandardCharsets.US_ASCII)); + getDeviceSession(channel, remoteAddress, buf.readSlice(12).toString(StandardCharsets.US_ASCII)); } else if (type == MSG_GPS_DATA) { @@ -67,21 +67,21 @@ public class RecodaProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(new Date(buf.readLong())); + position.setTime(new Date(buf.readLongLE())); int flags = buf.readUnsignedByte(); if (BitUtil.check(flags, 0)) { - buf.readUnsignedShort(); // declination + buf.readUnsignedShortLE(); // declination - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); position.setLongitude(buf.readUnsignedByte() + buf.readUnsignedByte() / 60.0); position.setLatitude(buf.readUnsignedByte() + buf.readUnsignedByte() / 60.0); - position.setLongitude(position.getLongitude() + buf.readUnsignedInt() / 3600.0); - position.setLatitude(position.getLatitude() + buf.readUnsignedInt() / 3600.0); + position.setLongitude(position.getLongitude() + buf.readUnsignedIntLE() / 3600.0); + position.setLatitude(position.getLatitude() + buf.readUnsignedIntLE() / 3600.0); int status = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/RetranslatorFrameDecoder.java b/src/org/traccar/protocol/RetranslatorFrameDecoder.java new file mode 100644 index 000000000..1ad07b8da --- /dev/null +++ b/src/org/traccar/protocol/RetranslatorFrameDecoder.java @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class RetranslatorFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int length = 4 + buf.getIntLE(buf.readerIndex()); + if (buf.readableBytes() >= length) { + return buf.readBytes(length); + } else { + return null; + } + } + +} diff --git a/src/org/traccar/protocol/RetranslatorProtocol.java b/src/org/traccar/protocol/RetranslatorProtocol.java new file mode 100644 index 000000000..725e37bd2 --- /dev/null +++ b/src/org/traccar/protocol/RetranslatorProtocol.java @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class RetranslatorProtocol extends BaseProtocol { + + public RetranslatorProtocol() { + super("retranslator"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new RetranslatorFrameDecoder()); + pipeline.addLast("objectDecoder", new RetranslatorProtocolDecoder(RetranslatorProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/org/traccar/protocol/RetranslatorProtocolDecoder.java new file mode 100644 index 000000000..b31dce5d7 --- /dev/null +++ b/src/org/traccar/protocol/RetranslatorProtocolDecoder.java @@ -0,0 +1,113 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class RetranslatorProtocolDecoder extends BaseProtocolDecoder { + + public RetranslatorProtocolDecoder(RetranslatorProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(new byte[]{0x11}), remoteAddress)); + } + + ByteBuf buf = (ByteBuf) msg; + + buf.readUnsignedInt(); // length + + int idLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x00) - buf.readerIndex(); + String id = buf.readBytes(idLength).toString(StandardCharsets.US_ASCII); + buf.readByte(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date(buf.readUnsignedInt() * 1000)); + + buf.readUnsignedInt(); // bit flags + + while (buf.isReadable()) { + + buf.readUnsignedShort(); // block type + int blockEnd = buf.readInt() + buf.readerIndex(); + buf.readUnsignedByte(); // security attribute + int dataType = buf.readUnsignedByte(); + + int nameLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x00) - buf.readerIndex(); + String name = buf.readBytes(nameLength).toString(StandardCharsets.US_ASCII); + buf.readByte(); + + if (name.equals("posinfo")) { + position.setValid(true); + position.setLongitude(buf.readDoubleLE()); + position.setLatitude(buf.readDoubleLE()); + position.setAltitude(buf.readDoubleLE()); + position.setSpeed(buf.readShort()); + position.setCourse(buf.readShort()); + position.set(Position.KEY_SATELLITES, buf.readByte()); + } else { + switch (dataType) { + case 1: + int len = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x00) - buf.readerIndex(); + position.set(name, buf.readBytes(len).toString(StandardCharsets.US_ASCII)); + buf.readByte(); + break; + case 3: + position.set(name, buf.readInt()); + break; + case 4: + position.set(name, buf.readDoubleLE()); + break; + case 5: + position.set(name, buf.readLong()); + break; + default: + break; + } + } + + buf.readerIndex(blockEnd); + + } + + if (position.getLatitude() == 0 && position.getLongitude() == 0) { + getLastLocation(position, position.getDeviceTime()); + } + + return position; + } + +} diff --git a/src/org/traccar/protocol/RitiProtocol.java b/src/org/traccar/protocol/RitiProtocol.java index 0ff3ce87b..9c2b93feb 100644 --- a/src/org/traccar/protocol/RitiProtocol.java +++ b/src/org/traccar/protocol/RitiProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.nio.ByteOrder; @@ -32,15 +31,14 @@ public class RitiProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 105, 2, 3, 0)); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", + new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); pipeline.addLast("objectDecoder", new RitiProtocolDecoder(RitiProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/RitiProtocolDecoder.java b/src/org/traccar/protocol/RitiProtocolDecoder.java index 637867908..4488db006 100644 --- a/src/org/traccar/protocol/RitiProtocolDecoder.java +++ b/src/org/traccar/protocol/RitiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; @@ -52,7 +52,7 @@ public class RitiProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header @@ -66,14 +66,14 @@ public class RitiProtocolDecoder extends BaseProtocolDecoder { position.set("mode", buf.readUnsignedByte()); position.set(Position.KEY_COMMAND, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); buf.skipBytes(5); // status - buf.readUnsignedShort(); // idleCount - buf.readUnsignedShort(); // idleTime in seconds + buf.readUnsignedShortLE(); // idleCount + buf.readUnsignedShortLE(); // idleTime in seconds - position.set(Position.KEY_DISTANCE, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); + position.set(Position.KEY_DISTANCE, buf.readUnsignedIntLE()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedIntLE()); // Parse GPRMC int end = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*'); diff --git a/src/org/traccar/protocol/RoboTrackFrameDecoder.java b/src/org/traccar/protocol/RoboTrackFrameDecoder.java new file mode 100644 index 000000000..aecbaaa3b --- /dev/null +++ b/src/org/traccar/protocol/RoboTrackFrameDecoder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class RoboTrackFrameDecoder extends BaseFrameDecoder { + + private int messageLength(ByteBuf buf) { + switch ((int) buf.getByte(buf.readerIndex())) { + case RoboTrackProtocolDecoder.MSG_ID: + return 69; + case RoboTrackProtocolDecoder.MSG_ACK: + return 3; + case RoboTrackProtocolDecoder.MSG_GPS: + case RoboTrackProtocolDecoder.MSG_GSM: + case RoboTrackProtocolDecoder.MSG_IMAGE_START: + return 24; + case RoboTrackProtocolDecoder.MSG_IMAGE_DATA: + return 8 + buf.getUnsignedShortLE(buf.readerIndex() + 1); + case RoboTrackProtocolDecoder.MSG_IMAGE_END: + return 6; + default: + return Integer.MAX_VALUE; + } + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int length = messageLength(buf); + + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/RoboTrackProtocol.java b/src/org/traccar/protocol/RoboTrackProtocol.java new file mode 100644 index 000000000..6ff670042 --- /dev/null +++ b/src/org/traccar/protocol/RoboTrackProtocol.java @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class RoboTrackProtocol extends BaseProtocol { + + public RoboTrackProtocol() { + super("robotrack"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new RoboTrackFrameDecoder()); + pipeline.addLast("objectDecoder", new RoboTrackProtocolDecoder(RoboTrackProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/org/traccar/protocol/RoboTrackProtocolDecoder.java new file mode 100644 index 000000000..587f9b8f7 --- /dev/null +++ b/src/org/traccar/protocol/RoboTrackProtocolDecoder.java @@ -0,0 +1,130 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class RoboTrackProtocolDecoder extends BaseProtocolDecoder { + + public RoboTrackProtocolDecoder(RoboTrackProtocol protocol) { + super(protocol); + } + + public static final int MSG_ID = 0x00; + public static final int MSG_ACK = 0x80; + public static final int MSG_GPS = 0x03; + public static final int MSG_GSM = 0x04; + public static final int MSG_IMAGE_START = 0x06; + public static final int MSG_IMAGE_DATA = 0x07; + public static final int MSG_IMAGE_END = 0x08; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + int type = buf.readUnsignedByte(); + + if (type == MSG_ID) { + + buf.skipBytes(16); // name + + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); + + if (getDeviceSession(channel, remoteAddress, imei) != null && channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeByte(MSG_ACK); + response.writeByte(0x01); // success + response.writeByte(0x66); // checksum + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + } else if (type == MSG_GPS || type == MSG_GSM) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); + + if (type == MSG_GPS) { + + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + position.setLatitude(buf.readIntLE() * 0.000001); + position.setLongitude(buf.readIntLE() * 0.000001); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readByte())); + + } else { + + getLastLocation(position, position.getDeviceTime()); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), + buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + + buf.readUnsignedByte(); // reserved + + } + + int value = buf.readUnsignedByte(); + + position.set(Position.KEY_SATELLITES, BitUtil.to(value, 4)); + position.set(Position.KEY_RSSI, BitUtil.between(value, 4, 7)); + position.set(Position.KEY_MOTION, BitUtil.check(value, 7)); + + value = buf.readUnsignedByte(); + + position.set(Position.KEY_CHARGE, BitUtil.check(value, 0)); + + for (int i = 1; i <= 4; i++) { + position.set(Position.PREFIX_IN + i, BitUtil.check(value, i)); + } + + position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(value, 5) * 100 / 7); + position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); + + for (int i = 1; i <= 3; i++) { + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE()); + } + + return position; + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/RuptelaProtocol.java b/src/org/traccar/protocol/RuptelaProtocol.java index fc3b17dd9..eb9bdada7 100644 --- a/src/org/traccar/protocol/RuptelaProtocol.java +++ b/src/org/traccar/protocol/RuptelaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -40,9 +39,9 @@ public class RuptelaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); pipeline.addLast("objectEncoder", new RuptelaProtocolEncoder()); pipeline.addLast("objectDecoder", new RuptelaProtocolDecoder(RuptelaProtocol.this)); diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java index 7b11cc5c3..e5d196fed 100644 --- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -48,7 +49,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SET_IO = 17; public static final int MSG_EXTENDED_RECORDS = 68; - private Position decodeCommandResponse(DeviceSession deviceSession, int type, ChannelBuffer buf) { + private Position decodeCommandResponse(DeviceSession deviceSession, int type, ByteBuf buf) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -73,7 +74,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } } - private long readValue(ChannelBuffer buf, int length, boolean signed) { + private long readValue(ByteBuf buf, int length, boolean signed) { switch (length) { case 1: return signed ? buf.readByte() : buf.readUnsignedByte(); @@ -86,7 +87,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeParameter(Position position, int id, ChannelBuffer buf, int length) { + private void decodeParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 2: case 3: @@ -114,7 +115,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedShort(); // data length @@ -196,7 +197,8 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("0002640113bc"))); + channel.writeAndFlush(new NetworkMessage( + Unpooled.wrappedBuffer(DataConverter.parseHex("0002640113bc")), remoteAddress)); } return positions; @@ -223,13 +225,14 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ARCHIVE, true); } - position.set(Position.KEY_DTCS, buf.readBytes(5).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DTCS, buf.readSlice(5).toString(StandardCharsets.US_ASCII)); positions.add(position); } if (channel != null) { - channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("00026d01c4a4"))); + channel.writeAndFlush(new NetworkMessage( + Unpooled.wrappedBuffer(DataConverter.parseHex("00026d01c4a4")), remoteAddress)); } return positions; diff --git a/src/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/org/traccar/protocol/RuptelaProtocolEncoder.java index 564d80869..28aa65273 100644 --- a/src/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.Log; @@ -26,14 +26,14 @@ import java.nio.charset.StandardCharsets; public class RuptelaProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(int type, ChannelBuffer content) { + private ByteBuf encodeContent(int type, ByteBuf content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeShort(1 + content.readableBytes()); buf.writeByte(100 + type); buf.writeBytes(content); - buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.toByteBuffer(2, buf.writerIndex() - 2))); + buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.nioBuffer(2, buf.writerIndex() - 2))); return buf; } @@ -41,7 +41,7 @@ public class RuptelaProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - ChannelBuffer content = ChannelBuffers.dynamicBuffer(); + ByteBuf content = Unpooled.buffer(); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/org/traccar/protocol/SabertekFrameDecoder.java b/src/org/traccar/protocol/SabertekFrameDecoder.java new file mode 100644 index 000000000..771ef9cfb --- /dev/null +++ b/src/org/traccar/protocol/SabertekFrameDecoder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class SabertekFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int beginIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02); + if (beginIndex >= 0) { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x03); + if (beginIndex >= 0) { + buf.readerIndex(beginIndex + 1); + ByteBuf frame = buf.readRetainedSlice(endIndex - beginIndex - 1); + buf.readerIndex(endIndex + 1); + buf.skipBytes(2); // end line + return frame; + } + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/SabertekProtocol.java b/src/org/traccar/protocol/SabertekProtocol.java new file mode 100644 index 000000000..55cb346ca --- /dev/null +++ b/src/org/traccar/protocol/SabertekProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class SabertekProtocol extends BaseProtocol { + + public SabertekProtocol() { + super("sabertek"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new SabertekFrameDecoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new SabertekProtocolDecoder(SabertekProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/SabertekProtocolDecoder.java b/src/org/traccar/protocol/SabertekProtocolDecoder.java new file mode 100644 index 000000000..8b7f2fb44 --- /dev/null +++ b/src/org/traccar/protocol/SabertekProtocolDecoder.java @@ -0,0 +1,134 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; +import java.util.regex.Pattern; + +public class SabertekProtocolDecoder extends BaseProtocolDecoder { + + public SabertekProtocolDecoder(SabertekProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text(",") + .number("(d+),") // id + .number("d,") // type + .groupBegin() + .number("d+,") // imei + .number("d+,") // scid + .expression("[^,]*,") // phone + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .groupEnd("?") + .number("(d+),") // battery + .number("(d+),") // rssi + .number("(d+),") // state + .number("(d+),") // events + .number("(d),") // valid + .number("(-?d+.d+),") // latitude + .number("(-?d+.d+),") // longitude + .number("(d+),") // speed + .number("(d+),") // course + .number("(d+),") // altitude + .number("(d+),") // satellites + .number("(d+),") // odometer + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage( + Unpooled.wrappedBuffer(new byte[]{(byte) (deviceSession != null ? 0x06 : 0x15)}), remoteAddress)); + } + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (parser.hasNext(6)) { + position.setTime(parser.nextDateTime()); + } else { + position.setTime(new Date()); + } + + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + + int state = parser.nextInt(); + + position.set(Position.KEY_IGNITION, BitUtil.check(state, 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(state, 1)); + + if (BitUtil.check(state, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); + } + if (BitUtil.check(state, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + + int events = parser.nextInt(); + + if (BitUtil.check(events, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } + if (BitUtil.check(events, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + if (BitUtil.check(events, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + } + if (BitUtil.check(events, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + + position.setValid(parser.nextInt() == 1); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextInt() * 1000L); + + return position; + } + +} diff --git a/src/org/traccar/protocol/SanavProtocol.java b/src/org/traccar/protocol/SanavProtocol.java index 4f463725e..e33a29db7 100644 --- a/src/org/traccar/protocol/SanavProtocol.java +++ b/src/org/traccar/protocol/SanavProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,10 +31,17 @@ public class SanavProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '*')); + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("objectDecoder", new SanavProtocolDecoder(SanavProtocol.this)); + } + }); + serverList.add(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new SanavProtocolDecoder(SanavProtocol.this)); diff --git a/src/org/traccar/protocol/SanavProtocolDecoder.java b/src/org/traccar/protocol/SanavProtocolDecoder.java index 714bb15d5..688157171 100644 --- a/src/org/traccar/protocol/SanavProtocolDecoder.java +++ b/src/org/traccar/protocol/SanavProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -33,7 +34,6 @@ public class SanavProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN = new PatternBuilder() - .any() .expression("imei[:=]") .number("(d+)") // imei .expression("&?rmc[:=]") @@ -47,6 +47,13 @@ public class SanavProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+),") // speed .number("(d+.d+)?,") // course .number("(dd)(dd)(dd),") // date (ddmmyy) + .groupBegin() + .expression("[^*]*") + .text("*") + .number("xx,") + .expression("[^,]+,") // status + .number("(d+),") // io + .groupEnd("?") .any() .compile(); @@ -59,26 +66,40 @@ public class SanavProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setValid(parser.next().equals("A")); position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); + position.setSpeed(parser.nextDouble()); position.setCourse(parser.nextDouble(0)); - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); + if (parser.hasNext()) { + int io = parser.nextInt(); + for (int i = 0; i < 5; i++) { + position.set(Position.PREFIX_IN + (i + 1), BitUtil.check(io, i)); + } + position.set(Position.KEY_IGNITION, BitUtil.check(io, 5)); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 6)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 7)); + position.set(Position.KEY_CHARGE, BitUtil.check(io, 8)); + if (!BitUtil.check(io, 9)) { + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + } + } + return position; } diff --git a/src/org/traccar/protocol/SigfoxProtocol.java b/src/org/traccar/protocol/SigfoxProtocol.java index 9feaea12d..4968a04ef 100644 --- a/src/org/traccar/protocol/SigfoxProtocol.java +++ b/src/org/traccar/protocol/SigfoxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,12 +32,12 @@ public class SigfoxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(65535)); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(65535)); pipeline.addLast("objectDecoder", new SigfoxProtocolDecoder(SigfoxProtocol.this)); } }); diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java index b454e00fa..f18eb015b 100644 --- a/src/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,11 @@ */ 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 io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DataConverter; @@ -31,7 +31,6 @@ import javax.json.JsonObject; 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; @@ -45,9 +44,9 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; + FullHttpRequest request = (FullHttpRequest) msg; JsonObject json = Json.createReader(new StringReader(URLDecoder.decode( - request.getContent().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject(); + request.content().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device")); if (deviceSession == null) { @@ -60,24 +59,26 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { position.setTime(new Date(json.getInt("time") * 1000L)); - ChannelBuffer buf = ChannelBuffers.wrappedBuffer( - ByteOrder.LITTLE_ENDIAN, DataConverter.parseHex(json.getString("data"))); + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(json.getString("data"))); + try { + int type = buf.readUnsignedByte() >> 4; + if (type == 0) { - int type = buf.readUnsignedByte() >> 4; - if (type == 0) { + position.setValid(true); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setCourse(buf.readUnsignedByte() * 2); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - 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); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025); + } else { - } else { - - getLastLocation(position, position.getDeviceTime()); + getLastLocation(position, position.getDeviceTime()); + } + } finally { + buf.release(); } position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue()); diff --git a/src/org/traccar/protocol/SiwiProtocol.java b/src/org/traccar/protocol/SiwiProtocol.java index 667e083f1..dba11f647 100644 --- a/src/org/traccar/protocol/SiwiProtocol.java +++ b/src/org/traccar/protocol/SiwiProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class SiwiProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new SiwiProtocolDecoder(SiwiProtocol.this)); diff --git a/src/org/traccar/protocol/SiwiProtocolDecoder.java b/src/org/traccar/protocol/SiwiProtocolDecoder.java index 66b6465fa..fc1296c64 100644 --- a/src/org/traccar/protocol/SiwiProtocolDecoder.java +++ b/src/org/traccar/protocol/SiwiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/SkypatrolProtocol.java b/src/org/traccar/protocol/SkypatrolProtocol.java index fba432522..2ce018dc8 100644 --- a/src/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/org/traccar/protocol/SkypatrolProtocol.java @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class SkypatrolProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); } }); diff --git a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java index a85595a07..054171914 100644 --- a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; @@ -54,7 +54,7 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; int apiNumber = buf.readUnsignedShort(); int commandType = buf.readUnsignedByte(); diff --git a/src/org/traccar/protocol/SmokeyProtocol.java b/src/org/traccar/protocol/SmokeyProtocol.java index 4f9a8dd74..7a4f416e6 100644 --- a/src/org/traccar/protocol/SmokeyProtocol.java +++ b/src/org/traccar/protocol/SmokeyProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class SmokeyProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new SmokeyProtocolDecoder(SmokeyProtocol.this)); } }); diff --git a/src/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/org/traccar/protocol/SmokeyProtocolDecoder.java index 9c4cb4e21..825108ed2 100644 --- a/src/org/traccar/protocol/SmokeyProtocolDecoder.java +++ b/src/org/traccar/protocol/SmokeyProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,14 +15,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Seconds; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -42,10 +44,10 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DATE_RECORD_ACK = 1; private static void sendResponse( - Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int index, int report) { + Channel channel, SocketAddress remoteAddress, ByteBuf id, int index, int report) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeBytes("SM".getBytes(StandardCharsets.US_ASCII)); response.writeByte(3); // protocol version response.writeByte(MSG_DATE_RECORD_ACK); @@ -57,11 +59,11 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { short checksum = (short) 0xF5A0; for (int i = 0; i < response.readableBytes(); i += 2) { - checksum ^= ChannelBuffers.swapShort(response.getShort(i)); + checksum ^= response.getShortLE(i); } response.writeShort(checksum); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -69,15 +71,15 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readUnsignedByte(); // protocol version int type = buf.readUnsignedByte(); - ChannelBuffer id = buf.readBytes(8); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(id)); + ByteBuf id = buf.readSlice(8); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); if (deviceSession == null) { return null; } diff --git a/src/org/traccar/protocol/SpotProtocol.java b/src/org/traccar/protocol/SpotProtocol.java index cd5ab90f6..f06eea17a 100644 --- a/src/org/traccar/protocol/SpotProtocol.java +++ b/src/org/traccar/protocol/SpotProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,12 +32,12 @@ public class SpotProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(65535)); + pipeline.addLast("httpAggregator", new HttpObjectAggregator(65535)); pipeline.addLast("objectDecoder", new SpotProtocolDecoder(SpotProtocol.this)); } }); diff --git a/src/org/traccar/protocol/SpotProtocolDecoder.java b/src/org/traccar/protocol/SpotProtocolDecoder.java index a8e666a32..16e287b6c 100644 --- a/src/org/traccar/protocol/SpotProtocolDecoder.java +++ b/src/org/traccar/protocol/SpotProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -16,9 +16,9 @@ package org.traccar.protocol; import com.fasterxml.jackson.databind.util.ByteBufferBackedInputStream; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateUtil; @@ -60,9 +60,9 @@ public class SpotProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - HttpRequest request = (HttpRequest) msg; + FullHttpRequest request = (FullHttpRequest) msg; - Document document = documentBuilder.parse(new ByteBufferBackedInputStream(request.getContent().toByteBuffer())); + Document document = documentBuilder.parse(new ByteBufferBackedInputStream(request.content().nioBuffer())); NodeList nodes = (NodeList) messageExpression.evaluate(document, XPathConstants.NODESET); List<Position> positions = new LinkedList<>(); diff --git a/src/org/traccar/protocol/StarLinkProtocol.java b/src/org/traccar/protocol/StarLinkProtocol.java index e71d94fd0..78178078c 100644 --- a/src/org/traccar/protocol/StarLinkProtocol.java +++ b/src/org/traccar/protocol/StarLinkProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class StarLinkProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java index f2c9d2c50..16c467e69 100644 --- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; diff --git a/src/org/traccar/protocol/Stl060FrameDecoder.java b/src/org/traccar/protocol/Stl060FrameDecoder.java index 455a869ee..f72474e2b 100644 --- a/src/org/traccar/protocol/Stl060FrameDecoder.java +++ b/src/org/traccar/protocol/Stl060FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; import org.traccar.CharacterDelimiterFrameDecoder; public class Stl060FrameDecoder extends CharacterDelimiterFrameDecoder { @@ -27,10 +26,9 @@ public class Stl060FrameDecoder extends CharacterDelimiterFrameDecoder { } @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { - ChannelBuffer result = (ChannelBuffer) super.decode(ctx, channel, buf); + ByteBuf result = (ByteBuf) super.decode(ctx, buf); if (result != null) { @@ -39,7 +37,7 @@ public class Stl060FrameDecoder extends CharacterDelimiterFrameDecoder { return result; } else { result.skipBytes(index); - return result.readBytes(result.readableBytes()); + return result.readRetainedSlice(result.readableBytes()); } } diff --git a/src/org/traccar/protocol/Stl060Protocol.java b/src/org/traccar/protocol/Stl060Protocol.java index 6fe2c5181..91440baa9 100644 --- a/src/org/traccar/protocol/Stl060Protocol.java +++ b/src/org/traccar/protocol/Stl060Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class Stl060Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Stl060FrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java index 64d4655c5..d997d2379 100644 --- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index 03a979d04..fdb8041cb 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -42,9 +41,9 @@ public class SuntechProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index b739e699b..b076546a6 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; @@ -239,7 +239,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (hbm) { if (index < values.length) { - position.set(Position.KEY_HOURS, Integer.parseInt(values[index++])); + position.set(Position.KEY_HOURS, UnitsConverter.msFromMinutes(Integer.parseInt(values[index++]))); } if (index < values.length) { diff --git a/src/org/traccar/protocol/SupermateProtocol.java b/src/org/traccar/protocol/SupermateProtocol.java index c9ae86fc1..847f9095c 100644 --- a/src/org/traccar/protocol/SupermateProtocol.java +++ b/src/org/traccar/protocol/SupermateProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class SupermateProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "#")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); @@ -43,4 +42,5 @@ public class SupermateProtocol extends BaseProtocol { } }); } + } diff --git a/src/org/traccar/protocol/SupermateProtocolDecoder.java b/src/org/traccar/protocol/SupermateProtocolDecoder.java index be325ea29..a5e93a673 100644 --- a/src/org/traccar/protocol/SupermateProtocolDecoder.java +++ b/src/org/traccar/protocol/SupermateProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -110,7 +111,8 @@ public class SupermateProtocolDecoder extends BaseProtocolDecoder { String content = String.format("#1:%s:1:*,00000000,UP,%02x%02x%02x,%02x%02x%02x#", imei, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); - channel.write(ChannelBuffers.copiedBuffer(content, StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer(content, StandardCharsets.US_ASCII), remoteAddress)); } return position; diff --git a/src/org/traccar/protocol/SviasProtocol.java b/src/org/traccar/protocol/SviasProtocol.java new file mode 100644 index 000000000..a811ddc9a --- /dev/null +++ b/src/org/traccar/protocol/SviasProtocol.java @@ -0,0 +1,57 @@ +/*
+ * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.CharacterDelimiterFrameDecoder;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+import org.traccar.model.Command;
+
+public class SviasProtocol extends BaseProtocol {
+
+ public SviasProtocol() {
+ super("svias");
+ setSupportedDataCommands(
+ Command.TYPE_CUSTOM,
+ Command.TYPE_POSITION_SINGLE,
+ Command.TYPE_SET_ODOMETER,
+ Command.TYPE_ENGINE_STOP,
+ Command.TYPE_ENGINE_RESUME,
+ Command.TYPE_ALARM_ARM,
+ Command.TYPE_ALARM_DISARM,
+ Command.TYPE_ALARM_REMOVE);
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "]"));
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectEncoder", new SviasProtocolEncoder());
+ pipeline.addLast("objectDecoder", new SviasProtocolDecoder(SviasProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/SviasProtocolDecoder.java b/src/org/traccar/protocol/SviasProtocolDecoder.java new file mode 100644 index 000000000..d6d755e19 --- /dev/null +++ b/src/org/traccar/protocol/SviasProtocolDecoder.java @@ -0,0 +1,104 @@ +/*
+ * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.NetworkMessage;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.PatternBuilder;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+import org.traccar.DeviceSession;
+import org.traccar.helper.Parser;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+public class SviasProtocolDecoder extends BaseProtocolDecoder {
+
+ public SviasProtocolDecoder(SviasProtocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("[") // delimiter
+ .number("d{4},") // hardware version
+ .number("d{4},") // software version
+ .number("d+,") // index
+ .number("(d+),") // imei
+ .number("d+,") // hour meter
+ .number("(d+)(dd)(dd),") // date (dmmyy)
+ .number("(d+)(dd)(dd),") // time (hmmss)
+ .number("(-?)(d+)(dd)(d{5}),") // latitude
+ .number("(-?)(d+)(dd)(d{5}),") // longitude
+ .number("(d+),") // speed
+ .number("(d+),") // course
+ .number("(d+),") // odometer
+ .number("(d+),") // input
+ .number("(d+),") // output / status
+ .number("(d),")
+ .number("(d),")
+ .number("(d+),") // power
+ .number("(d+),") // battery level
+ .number("(d+),") // rssi
+ .any()
+ .compile();
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg)
+ throws Exception {
+
+ if (channel != null) {
+ channel.writeAndFlush(new NetworkMessage("@", remoteAddress));
+ }
+
+ Parser parser = new Parser(PATTERN, (String) msg);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN));
+ position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN));
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble() * 0.01));
+ position.setCourse(parser.nextDouble() * 0.01);
+
+ position.set(Position.KEY_ODOMETER, parser.nextInt() * 100);
+
+ int input = parser.nextInt();
+ int output = parser.nextInt();
+
+ position.set(Position.KEY_ALARM, BitUtil.check(input, 0) ? Position.ALARM_SOS : null);
+ position.set(Position.KEY_IGNITION, BitUtil.check(input, 4));
+ position.setValid(BitUtil.check(output, 0));
+
+ position.set(Position.KEY_POWER, parser.nextInt() * 0.001);
+ position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/SviasProtocolEncoder.java b/src/org/traccar/protocol/SviasProtocolEncoder.java new file mode 100644 index 000000000..c26ee2032 --- /dev/null +++ b/src/org/traccar/protocol/SviasProtocolEncoder.java @@ -0,0 +1,51 @@ +/*
+ * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.StringProtocolEncoder;
+import org.traccar.helper.Log;
+import org.traccar.model.Command;
+
+public class SviasProtocolEncoder extends StringProtocolEncoder {
+
+ @Override
+ protected Object encodeCommand(Command command) {
+ switch (command.getType()) {
+ case Command.TYPE_CUSTOM:
+ return formatCommand(command, "{%s}", Command.KEY_DATA);
+ case Command.TYPE_POSITION_SINGLE:
+ return formatCommand(command, "AT+STR=1*");
+ case Command.TYPE_SET_ODOMETER:
+ return formatCommand(command, "AT+ODT={%s}*", Command.KEY_DATA);
+ case Command.TYPE_ENGINE_STOP:
+ return formatCommand(command, "AT+OUT=1,1*");
+ case Command.TYPE_ENGINE_RESUME:
+ return formatCommand(command, "AT+OUT=1,0*");
+ case Command.TYPE_ALARM_ARM:
+ return formatCommand(command, "AT+OUT=2,1*");
+ case Command.TYPE_ALARM_DISARM:
+ return formatCommand(command, "AT+OUT=2,0*");
+ case Command.TYPE_ALARM_REMOVE:
+ return formatCommand(command, "AT+PNC=600*");
+ default:
+ Log.warning(new UnsupportedOperationException(command.getType()));
+ break;
+ }
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/T55Protocol.java b/src/org/traccar/protocol/T55Protocol.java index 402fd46b8..b69cfab6f 100644 --- a/src/org/traccar/protocol/T55Protocol.java +++ b/src/org/traccar/protocol/T55Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -34,18 +32,18 @@ public class T55Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new T55ProtocolDecoder(T55Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new T55ProtocolDecoder(T55Protocol.this)); diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index be3cb5f67..8aa7fae8f 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -15,17 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.socket.DatagramChannel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.channels.DatagramChannel; import java.util.Date; import java.util.regex.Pattern; @@ -53,7 +54,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .number(",(d+)") // imei .expression(",([01])") // ignition .number(",(d+)") // fuel - .number(",(d+)").optional(5) // battery + .number(",(d+)").optional(7) // battery .number("((?:,d+)+)?") // parameters .any() .compile(); @@ -102,7 +103,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) && Context.getIdentityManager().lookupAttributeBoolean( deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) { - channel.write("OK1\r\n"); + channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); } Parser parser = new Parser(PATTERN_GPRMC, sentence); diff --git a/src/org/traccar/protocol/T57FrameDecoder.java b/src/org/traccar/protocol/T57FrameDecoder.java index b3b456516..14ba31453 100644 --- a/src/org/traccar/protocol/T57FrameDecoder.java +++ b/src/org/traccar/protocol/T57FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,18 +15,18 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; import java.nio.charset.StandardCharsets; -public class T57FrameDecoder extends FrameDecoder { +public class T57FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; @@ -43,7 +43,7 @@ public class T57FrameDecoder extends FrameDecoder { } } - return index > 0 ? buf.readBytes(index + 1 - buf.readerIndex()) : null; + return index > 0 ? buf.readRetainedSlice(index + 1 - buf.readerIndex()) : null; } } diff --git a/src/org/traccar/protocol/T57Protocol.java b/src/org/traccar/protocol/T57Protocol.java index 5149929e9..9f3dd62a3 100644 --- a/src/org/traccar/protocol/T57Protocol.java +++ b/src/org/traccar/protocol/T57Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class T57Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new T57FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/T57ProtocolDecoder.java b/src/org/traccar/protocol/T57ProtocolDecoder.java index 65dfc46e3..441f8cf8a 100644 --- a/src/org/traccar/protocol/T57ProtocolDecoder.java +++ b/src/org/traccar/protocol/T57ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/T800xProtocol.java b/src/org/traccar/protocol/T800xProtocol.java index 830ff4de6..26f34ee77 100644 --- a/src/org/traccar/protocol/T800xProtocol.java +++ b/src/org/traccar/protocol/T800xProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -34,9 +33,9 @@ public class T800xProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); pipeline.addLast("objectEncoder", new T800xProtocolEncoder()); pipeline.addLast("objectDecoder", new T800xProtocolDecoder(T800xProtocol.this)); diff --git a/src/org/traccar/protocol/T800xProtocolDecoder.java b/src/org/traccar/protocol/T800xProtocolDecoder.java index 1fd37864e..d5504c190 100644 --- a/src/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/org/traccar/protocol/T800xProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; @@ -29,7 +31,6 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; -import java.nio.ByteOrder; public class T800xProtocolDecoder extends BaseProtocolDecoder { @@ -43,22 +44,15 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_ALARM = 0x04; public static final int MSG_COMMAND = 0x81; - private static float readSwappedFloat(ChannelBuffer buf) { - byte[] bytes = new byte[4]; - buf.readBytes(bytes); - return ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, bytes).readFloat(); - } - - private void sendResponse(Channel channel, int type, ChannelBuffer imei) { + private void sendResponse(Channel channel, short header, int type, ByteBuf imei) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(15); - response.writeByte(0x23); - response.writeByte(0x23); // header + ByteBuf response = Unpooled.buffer(15); + response.writeShort(header); response.writeByte(type); response.writeShort(response.capacity()); // length response.writeShort(0x0001); // index response.writeBytes(imei); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -85,22 +79,22 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - buf.skipBytes(2); + short header = buf.readShort(); int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // length int index = buf.readUnsignedShort(); - ChannelBuffer imei = buf.readBytes(8); + ByteBuf imei = buf.readSlice(8); DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, ChannelBuffers.hexDump(imei).substring(1)); + channel, remoteAddress, ByteBufUtil.hexDump(imei).substring(1)); if (deviceSession == null) { return null; } if (type == MSG_LOGIN || type == MSG_ALARM || type == MSG_HEARTBEAT) { - sendResponse(channel, type, imei); + sendResponse(channel, header, type, imei); } if (type == MSG_GPS || type == MSG_ALARM) { @@ -116,7 +110,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // distance compensation buf.readUnsignedShort(); // speed alarm - int locationStatus = buf.readUnsignedByte(); + int status = buf.readUnsignedByte(); buf.readUnsignedByte(); // gsensor manager status buf.readUnsignedByte(); // other flags @@ -151,31 +145,36 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { .setMinute(BcdUtil.readInteger(buf, 2)) .setSecond(BcdUtil.readInteger(buf, 2)); - if (BitUtil.check(locationStatus, 6)) { + if (BitUtil.check(status, 6)) { - position.setValid(!BitUtil.check(locationStatus, 7)); + position.setValid(!BitUtil.check(status, 7)); position.setTime(dateBuilder.getDate()); - position.setAltitude(readSwappedFloat(buf)); - position.setLongitude(readSwappedFloat(buf)); - position.setLatitude(readSwappedFloat(buf)); - position.setSpeed(UnitsConverter.knotsFromKph( - BcdUtil.readInteger(buf, 4) * 0.1)); + position.setAltitude(buf.readFloatLE()); + position.setLongitude(buf.readFloatLE()); + position.setLatitude(buf.readFloatLE()); + position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4) * 0.1)); position.setCourse(buf.readUnsignedShort()); } else { getLastLocation(position, dateBuilder.getDate()); - byte[] array = new byte[16]; - buf.readBytes(array); - ChannelBuffer swapped = ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, array); + int mcc = buf.readUnsignedShortLE(); + int mnc = buf.readUnsignedShortLE(); - position.setNetwork(new Network(CellTower.from( - swapped.readUnsignedShort(), swapped.readUnsignedShort(), - swapped.readUnsignedShort(), swapped.readUnsignedShort()))); + if (mcc != 0xffff && mnc != 0xffff) { + Network network = new Network(); + for (int i = 0; i < 3; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShortLE(), buf.readUnsignedShortLE())); + } + position.setNetwork(network); + } - // two more cell towers + } + if (buf.readableBytes() >= 2) { + position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01); } return position; diff --git a/src/org/traccar/protocol/T800xProtocolEncoder.java b/src/org/traccar/protocol/T800xProtocolEncoder.java index 038a5e51a..ba17c9d75 100644 --- a/src/org/traccar/protocol/T800xProtocolEncoder.java +++ b/src/org/traccar/protocol/T800xProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.helper.Log; @@ -30,9 +30,9 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder { public static final int MODE_BROADCAST = 0x02; public static final int MODE_FORWARD = 0x03; - private ChannelBuffer encodeContent(Command command, String content) { + private ByteBuf encodeContent(Command command, String content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeByte('#'); buf.writeByte('#'); diff --git a/src/org/traccar/protocol/TaipProtocol.java b/src/org/traccar/protocol/TaipProtocol.java index cbfc44122..bfecf9b39 100644 --- a/src/org/traccar/protocol/TaipProtocol.java +++ b/src/org/traccar/protocol/TaipProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -34,18 +32,18 @@ public class TaipProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '<')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this)); diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index a7aa9dd96..31b435bce 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; @@ -178,7 +179,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 2, parser.nextInt() * 0.01); } - position.setValid(valid != null ? valid : true); + position.setValid(valid == null || valid); if (event != null) { position.set(Position.KEY_EVENT, event); @@ -271,9 +272,9 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { if (messageIndex != null) { String response = ">ACK;ID=" + uniqueId + ";" + messageIndex + ";*"; response += String.format("%02X", Checksum.xor(response)) + "<"; - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { - channel.write(uniqueId, remoteAddress); + channel.writeAndFlush(new NetworkMessage(uniqueId, remoteAddress)); } } return position; diff --git a/src/org/traccar/protocol/TelemaxProtocol.java b/src/org/traccar/protocol/TelemaxProtocol.java new file mode 100644 index 000000000..f2208741a --- /dev/null +++ b/src/org/traccar/protocol/TelemaxProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class TelemaxProtocol extends BaseProtocol { + + public TelemaxProtocol() { + super("telemax"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new TelemaxProtocolDecoder(TelemaxProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/TelemaxProtocolDecoder.java b/src/org/traccar/protocol/TelemaxProtocolDecoder.java new file mode 100644 index 000000000..fd2f03e1c --- /dev/null +++ b/src/org/traccar/protocol/TelemaxProtocolDecoder.java @@ -0,0 +1,111 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +public class TelemaxProtocolDecoder extends BaseProtocolDecoder { + + public TelemaxProtocolDecoder(TelemaxProtocol protocol) { + super(protocol); + } + + private String readValue(String sentence, int[] index, int length) { + String value = sentence.substring(index[0], index[0] + length); + index[0] += length; + return value; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + if (sentence.startsWith("%")) { + int length = Integer.parseInt(sentence.substring(1, 3)); + getDeviceSession(channel, remoteAddress, sentence.substring(3, 3 + length)); + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + int[] index = {0}; + + if (!readValue(sentence, index, 1).equals("Y")) { + return null; + } + + readValue(sentence, index, 8); // command id + readValue(sentence, index, 6); // password + readValue(sentence, index, Integer.parseInt(readValue(sentence, index, 2), 16)); // unit id + readValue(sentence, index, 2); // frame count + + readValue(sentence, index, 2); // data format + + int interval = Integer.parseInt(readValue(sentence, index, 4), 16); + + readValue(sentence, index, 2); // info flags + readValue(sentence, index, 2); // version + + int count = Integer.parseInt(readValue(sentence, index, 2), 16); + + Date time = null; + List<Position> positions = new LinkedList<>(); + + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + int speed = Integer.parseInt(readValue(sentence, index, 2), 16); + + position.setValid(BitUtil.check(speed, 7)); + position.setSpeed(BitUtil.to(speed, 7)); + + position.setLongitude((Integer.parseInt(readValue(sentence, index, 6), 16) - 5400000) / 30000.0); + position.setLatitude((Integer.parseInt(readValue(sentence, index, 6), 16) - 5400000) / 30000.0); + + if (i == 0 | i == count - 1) { + time = new SimpleDateFormat("yyMMddhhmmss").parse(readValue(sentence, index, 12)); + position.set(Position.KEY_STATUS, readValue(sentence, index, 8)); + } else { + time = new Date(time.getTime() + interval * 1000); + } + + position.setTime(time); + + positions.add(position); + + } + + return positions; + } + +} diff --git a/src/org/traccar/protocol/TelicFrameDecoder.java b/src/org/traccar/protocol/TelicFrameDecoder.java index 245be28fb..d1fef1b5b 100644 --- a/src/org/traccar/protocol/TelicFrameDecoder.java +++ b/src/org/traccar/protocol/TelicFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,32 +15,33 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class TelicFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class TelicFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 4) { return null; } - long length = buf.getUnsignedInt(buf.readerIndex()); + long length = buf.getUnsignedIntLE(buf.readerIndex()); if (length < 1024) { if (buf.readableBytes() >= length + 4) { - buf.readUnsignedInt(); - return buf.readBytes((int) length); + buf.readUnsignedIntLE(); + return buf.readRetainedSlice((int) length); } } else { int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); if (endIndex >= 0) { - ChannelBuffer frame = buf.readBytes(endIndex - buf.readerIndex()); + ByteBuf frame = buf.readRetainedSlice(endIndex - buf.readerIndex()); buf.readByte(); if (frame.readableBytes() > 0) { return frame; diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java index fdd0b94c6..0ee4cf165 100644 --- a/src/org/traccar/protocol/TelicProtocol.java +++ b/src/org/traccar/protocol/TelicProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,12 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class TelicProtocol extends BaseProtocol { @@ -33,17 +31,15 @@ public class TelicProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new TelicFrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new TelicProtocolDecoder(TelicProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 197db059b..3a9962361 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/org/traccar/protocol/TeltonikaFrameDecoder.java index e7313b722..4d4d79d8d 100644 --- a/src/org/traccar/protocol/TeltonikaFrameDecoder.java +++ b/src/org/traccar/protocol/TeltonikaFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,20 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class TeltonikaFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class TeltonikaFrameDecoder extends BaseFrameDecoder { private static final int MESSAGE_MINIMUM_LENGTH = 12; @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { // Check minimum length if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { @@ -39,12 +38,12 @@ public class TeltonikaFrameDecoder extends FrameDecoder { int length = buf.getUnsignedShort(buf.readerIndex()); if (length > 0) { if (buf.readableBytes() >= (length + 2)) { - return buf.readBytes(length + 2); + return buf.readRetainedSlice(length + 2); } } else { int dataLength = buf.getInt(buf.readerIndex() + 4); if (buf.readableBytes() >= (dataLength + 12)) { - return buf.readBytes(dataLength + 12); + return buf.readRetainedSlice(dataLength + 12); } } diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java index d0177da97..d5e10de03 100644 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/org/traccar/protocol/TeltonikaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -34,17 +32,17 @@ public class TeltonikaProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new TeltonikaFrameDecoder()); pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index d2069e6c9..5e9b6640e 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -15,12 +15,14 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; @@ -48,20 +50,20 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { this.extended = Context.getConfig().getBoolean(getProtocolName() + ".extended"); } - private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedShort(); String imei = buf.toString(buf.readerIndex(), length, StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(1); + ByteBuf response = Unpooled.buffer(1); if (deviceSession != null) { response.writeByte(1); } else { response.writeByte(0); } - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return deviceSession; } @@ -71,17 +73,17 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { public static final int CODEC_12 = 0x0C; public static final int CODEC_16 = 0x10; - private void decodeSerial(Position position, ChannelBuffer buf) { + private void decodeSerial(Position position, ByteBuf buf) { getLastLocation(position, null); position.set(Position.KEY_TYPE, buf.readUnsignedByte()); - position.set(Position.KEY_RESULT, buf.readBytes(buf.readInt()).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_RESULT, buf.readSlice(buf.readInt()).toString(StandardCharsets.US_ASCII)); } - private long readValue(ChannelBuffer buf, int length, boolean signed) { + private long readValue(ByteBuf buf, int length, boolean signed) { switch (length) { case 1: return signed ? buf.readByte() : buf.readUnsignedByte(); @@ -94,7 +96,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeOtherParameter(Position position, int id, ChannelBuffer buf, int length) { + private void decodeOtherParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: case 2: @@ -141,6 +143,16 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set("workMode", readValue(buf, length, false)); break; + case 129: + case 130: + case 131: + case 132: + case 133: + case 134: + String driver = id == 129 || id == 132 ? "" : position.getString("driver1"); + position.set("driver" + (id >= 132 ? 2 : 1), + driver + buf.readSlice(length).toString(StandardCharsets.US_ASCII).trim()); + break; case 179: position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); break; @@ -153,6 +165,29 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); break; + case 236: + if (readValue(buf, length, false) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + break; + case 237: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 0); + break; + case 238: + switch ((int) readValue(buf, length, false)) { + case 1: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 2: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 3: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + break; + } + break; case 239: position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); break; @@ -168,7 +203,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeGh3000Parameter(Position position, int id, ChannelBuffer buf, int length) { + private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); @@ -211,7 +246,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeParameter(Position position, int id, ChannelBuffer buf, int length, int codec) { + private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec) { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { @@ -232,7 +267,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeLocation(Position position, ChannelBuffer buf, int codec) { + private void decodeLocation(Position position, ByteBuf buf, int codec) { int globalMask = 0x0f; @@ -359,7 +394,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (extended) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - position.set(Position.PREFIX_IO + buf.readUnsignedByte(), ChannelBuffers.hexDump(buf.readBytes(16))); + position.set(Position.PREFIX_IO + buf.readUnsignedByte(), ByteBufUtil.hexDump(buf.readSlice(16))); } } @@ -368,7 +403,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } private List<Position> parseData( - Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int locationPacketId, String... imei) { + Channel channel, SocketAddress remoteAddress, ByteBuf buf, int locationPacketId, String... imei) { List<Position> positions = new LinkedList<>(); if (!connectionless) { @@ -400,17 +435,17 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { if (connectionless) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeShort(5); response.writeShort(0); response.writeByte(0x01); response.writeByte(locationPacketId); response.writeByte(count); - channel.write(response, remoteAddress); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeInt(count); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -420,7 +455,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (connectionless) { return decodeUdp(channel, remoteAddress, buf); @@ -429,7 +464,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); @@ -441,13 +476,13 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { buf.readUnsignedShort(); // length buf.readUnsignedShort(); // packet id buf.readUnsignedByte(); // packet type int locationPacketId = buf.readUnsignedByte(); - String imei = buf.readBytes(buf.readUnsignedShort()).toString(StandardCharsets.US_ASCII); + String imei = buf.readSlice(buf.readUnsignedShort()).toString(StandardCharsets.US_ASCII); return parseData(channel, remoteAddress, buf, locationPacketId, imei); diff --git a/src/org/traccar/protocol/TeltonikaProtocolEncoder.java b/src/org/traccar/protocol/TeltonikaProtocolEncoder.java index fd6eae744..f2680c27c 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolEncoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,20 +15,21 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.model.Command; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + import java.nio.charset.StandardCharsets; public class TeltonikaProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(String content) { + private ByteBuf encodeContent(String content) { - ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + ByteBuf buf = Unpooled.buffer(); buf.writeInt(0); buf.writeInt(content.length() + 10); @@ -40,7 +41,7 @@ public class TeltonikaProtocolEncoder extends BaseProtocolEncoder { buf.writeByte('\r'); buf.writeByte('\n'); buf.writeByte(1); // quantity - buf.writeInt(Checksum.crc16(Checksum.CRC16_IBM, buf.toByteBuffer(8, buf.writerIndex() - 8))); + buf.writeInt(Checksum.crc16(Checksum.CRC16_IBM, buf.nioBuffer(8, buf.writerIndex() - 8))); return buf; } diff --git a/src/org/traccar/protocol/ThinkRaceProtocol.java b/src/org/traccar/protocol/ThinkRaceProtocol.java index 98f43e2e3..644e16ca7 100644 --- a/src/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/org/traccar/protocol/ThinkRaceProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class ThinkRaceProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); pipeline.addLast("objectDecoder", new ThinkRaceProtocolDecoder(ThinkRaceProtocol.this)); } diff --git a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java index f7dd18f51..451f1c448 100644 --- a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -52,10 +53,10 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header - ChannelBuffer id = buf.readBytes(12); + ByteBuf id = buf.readSlice(12); buf.readUnsignedByte(); // separator int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // length @@ -68,7 +69,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { String imei = buf.toString(buf.readerIndex(), 15, StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null && channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(0x48); response.writeByte(0x52); // header response.writeBytes(id); response.writeByte(0x2c); // separator @@ -76,7 +77,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0x0002); // length response.writeShort(0x8000); response.writeShort(0x0000); // checksum - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } diff --git a/src/org/traccar/protocol/Tk102Protocol.java b/src/org/traccar/protocol/Tk102Protocol.java index 962f2401b..2eff262f0 100644 --- a/src/org/traccar/protocol/Tk102Protocol.java +++ b/src/org/traccar/protocol/Tk102Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class Tk102Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); pipeline.addLast("objectDecoder", new Tk102ProtocolDecoder(Tk102Protocol.this)); } diff --git a/src/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/org/traccar/protocol/Tk102ProtocolDecoder.java index 50dd45676..c3ba6d303 100644 --- a/src/org/traccar/protocol/Tk102ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk102ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -59,16 +60,17 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder { .text(")") .compile(); - private void sendResponse(Channel channel, int type, ChannelBuffer dataSequence, ChannelBuffer content) { + private void sendResponse(Channel channel, int type, ByteBuf dataSequence, ByteBuf content) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte('['); response.writeByte(type); response.writeBytes(dataSequence); response.writeByte(content.readableBytes()); response.writeBytes(content); + content.release(); response.writeByte(']'); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -76,16 +78,16 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(1); // header int type = buf.readUnsignedByte(); - ChannelBuffer dataSequence = buf.readBytes(10); + ByteBuf dataSequence = buf.readSlice(10); int length = buf.readUnsignedByte(); if (type == MSG_LOGIN_REQUEST || type == MSG_LOGIN_REQUEST_2) { - ChannelBuffer data = buf.readBytes(length); + ByteBuf data = buf.readSlice(length); String id; if (type == MSG_LOGIN_REQUEST) { @@ -95,7 +97,7 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder { } if (getDeviceSession(channel, remoteAddress, id) != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(MODE_GPRS); response.writeBytes(data); sendResponse(channel, MSG_LOGIN_RESPONSE, dataSequence, response); @@ -103,7 +105,7 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_HEARTBEAT_REQUEST) { - sendResponse(channel, MSG_HEARTBEAT_RESPONSE, dataSequence, buf.readBytes(length)); + sendResponse(channel, MSG_HEARTBEAT_RESPONSE, dataSequence, buf.readRetainedSlice(length)); } else { @@ -112,7 +114,7 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder { return null; } - Parser parser = new Parser(PATTERN, buf.readBytes(length).toString(StandardCharsets.US_ASCII)); + Parser parser = new Parser(PATTERN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); if (!parser.matches()) { return null; } diff --git a/src/org/traccar/protocol/Tk103FrameDecoder.java b/src/org/traccar/protocol/Tk103FrameDecoder.java index 390e38906..b61a42563 100644 --- a/src/org/traccar/protocol/Tk103FrameDecoder.java +++ b/src/org/traccar/protocol/Tk103FrameDecoder.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Valerii Vyshniak (val@val.one) - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -16,16 +16,16 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -public class Tk103FrameDecoder extends FrameDecoder { +public class Tk103FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 2) { return null; @@ -69,7 +69,7 @@ public class Tk103FrameDecoder extends FrameDecoder { buf.readerIndex(frameStartIndex); - return buf.readBytes(frameEndIndex + 1 - frameStartIndex); + return buf.readRetainedSlice(frameEndIndex + 1 - frameStartIndex); } } diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java index 6ef9c0a56..ff31f16bc 100644 --- a/src/org/traccar/protocol/Tk103Protocol.java +++ b/src/org/traccar/protocol/Tk103Protocol.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Christoph Krey (c@ckrey.de) - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -16,12 +16,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -47,14 +45,15 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE, Command.TYPE_SET_ODOMETER, Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); + Command.TYPE_ENGINE_RESUME, + Command.TYPE_OUTPUT_CONTROL); } @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Tk103FrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); @@ -62,9 +61,9 @@ public class Tk103Protocol extends BaseProtocol { pipeline.addLast("objectDecoder", new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Tk103ProtocolEncoder()); diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 22a73469f..fd208d526 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,10 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -349,10 +350,10 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { String id = sentence.substring(1, 13); String type = sentence.substring(13, 17); if (type.equals("BP00")) { - channel.write("(" + id + "AP01HSO)"); + channel.writeAndFlush(new NetworkMessage("(" + id + "AP01HSO)", remoteAddress)); return null; } else if (type.equals("BP05")) { - channel.write("(" + id + "AP05)"); + channel.writeAndFlush(new NetworkMessage("(" + id + "AP05)", remoteAddress)); } } diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java index 946f3ad73..d64c85c2c 100644 --- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -47,6 +47,8 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { if (alternative) { switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatAlt(command, "{%s}", Command.KEY_DATA); case Command.TYPE_GET_VERSION: return formatAlt(command, "*about*"); case Command.TYPE_REBOOT_DEVICE: @@ -57,8 +59,6 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { return formatAlt(command, "*routetrack*99*"); case Command.TYPE_POSITION_STOP: return formatAlt(command, "*routetrackoff*"); - case Command.TYPE_CUSTOM: - return formatAlt(command, "{%s}", Command.KEY_DATA); case Command.TYPE_GET_DEVICE_STATUS: return formatAlt(command, "*status*"); case Command.TYPE_IDENTIFICATION: @@ -80,6 +80,8 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { } } else { switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, "({%s}{%s})", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_GET_VERSION: return formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID); case Command.TYPE_REBOOT_DEVICE: @@ -97,6 +99,8 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { return formatCommand(command, "({%s}AV010)", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL: + return formatCommand(command, "({%s}AV00{%s})", Command.KEY_UNIQUE_ID, Command.KEY_DATA); default: Log.warning(new UnsupportedOperationException(command.getType())); return null; diff --git a/src/org/traccar/protocol/Tlt2hProtocol.java b/src/org/traccar/protocol/Tlt2hProtocol.java index 752b0d8ef..1a23dee40 100644 --- a/src/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/org/traccar/protocol/Tlt2hProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Tlt2hProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/org/traccar/protocol/Tlt2hProtocolDecoder.java index a5a195afa..780785247 100644 --- a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/TlvProtocol.java b/src/org/traccar/protocol/TlvProtocol.java index da8d88b8a..ddc8d2a6e 100644 --- a/src/org/traccar/protocol/TlvProtocol.java +++ b/src/org/traccar/protocol/TlvProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,10 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -31,9 +30,9 @@ public class TlvProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder('\0')); pipeline.addLast("objectDecoder", new TlvProtocolDecoder(TlvProtocol.this)); } diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java index 0cf68acb8..d3ce4e072 100644 --- a/src/org/traccar/protocol/TlvProtocolDecoder.java +++ b/src/org/traccar/protocol/TlvProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -33,43 +34,43 @@ public class TlvProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void sendResponse(Channel channel, String type, String... arguments) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, String... arguments) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); - response.writeBytes(ChannelBuffers.copiedBuffer(type, StandardCharsets.US_ASCII)); + ByteBuf response = Unpooled.buffer(); + response.writeCharSequence(type, StandardCharsets.US_ASCII); for (String argument : arguments) { response.writeByte(argument.length()); - response.writeBytes(ChannelBuffers.copiedBuffer(argument, StandardCharsets.US_ASCII)); + response.writeCharSequence(argument, StandardCharsets.US_ASCII); } response.writeByte(0); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } - private String readArgument(ChannelBuffer buf) { - return buf.readBytes(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII); + private String readArgument(ByteBuf buf) { + return buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII); } @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; - String type = buf.readBytes(2).toString(StandardCharsets.US_ASCII); + String type = buf.readSlice(2).toString(StandardCharsets.US_ASCII); if (channel != null) { switch (type) { case "0A": case "0C": - sendResponse(channel, type); + sendResponse(channel, remoteAddress, type); break; case "0B": - sendResponse(channel, type, "1482202689", "10", "20", "15"); + sendResponse(channel, remoteAddress, type, "1482202689", "10", "20", "15"); break; case "0E": case "0F": - sendResponse(channel, type, "30", "Unknown"); + sendResponse(channel, remoteAddress, type, "30", "Unknown"); break; default: break; diff --git a/src/org/traccar/protocol/TmgFrameDecoder.java b/src/org/traccar/protocol/TmgFrameDecoder.java index c39cf03ac..205adaa51 100644 --- a/src/org/traccar/protocol/TmgFrameDecoder.java +++ b/src/org/traccar/protocol/TmgFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,34 +15,37 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBufferIndexFinder; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class TmgFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class TmgFrameDecoder extends BaseFrameDecoder { private boolean isLetter(byte c) { return c >= 'a' && c <= 'z'; } - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { - - int beginIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new ChannelBufferIndexFinder() { - @Override - public boolean find(ChannelBuffer buffer, int guessedIndex) { - if (buffer.getByte(guessedIndex) != (byte) '$' || buffer.writerIndex() - guessedIndex < 5) { - return false; - } - return buffer.getByte(guessedIndex + 4) == ',' + private int findHeader(ByteBuf buffer) { + int guessedIndex = buffer.indexOf(buffer.readerIndex(), buffer.writerIndex(), (byte) '$'); + while (guessedIndex != -1 && buffer.writerIndex() - guessedIndex >= 5) { + if (buffer.getByte(guessedIndex + 4) == ',' && isLetter(buffer.getByte(guessedIndex + 1)) && isLetter(buffer.getByte(guessedIndex + 2)) - && isLetter(buffer.getByte(guessedIndex + 3)); + && isLetter(buffer.getByte(guessedIndex + 3))) { + return guessedIndex; } - }); + guessedIndex = buffer.indexOf(guessedIndex, buffer.writerIndex(), (byte) '$'); + } + return -1; + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int beginIndex = findHeader(buf); if (beginIndex >= 0) { @@ -51,7 +54,7 @@ public class TmgFrameDecoder extends FrameDecoder { int endIndex = buf.indexOf(beginIndex, buf.writerIndex(), (byte) '\n'); if (endIndex >= 0) { - ChannelBuffer frame = buf.readBytes(endIndex - beginIndex); + ByteBuf frame = buf.readRetainedSlice(endIndex - beginIndex); buf.readByte(); // delimiter return frame; } diff --git a/src/org/traccar/protocol/TmgProtocol.java b/src/org/traccar/protocol/TmgProtocol.java index c11762cac..192891100 100644 --- a/src/org/traccar/protocol/TmgProtocol.java +++ b/src/org/traccar/protocol/TmgProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class TmgProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new TmgFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java index cb10eedd7..7ac443d5c 100644 --- a/src/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/org/traccar/protocol/TmgProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; diff --git a/src/org/traccar/protocol/TopflytechProtocol.java b/src/org/traccar/protocol/TopflytechProtocol.java index 7d4b13ee6..03eb4b3ea 100644 --- a/src/org/traccar/protocol/TopflytechProtocol.java +++ b/src/org/traccar/protocol/TopflytechProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class TopflytechProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/org/traccar/protocol/TopflytechProtocolDecoder.java index b3a8fa845..4ce161b1c 100644 --- a/src/org/traccar/protocol/TopflytechProtocolDecoder.java +++ b/src/org/traccar/protocol/TopflytechProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/TotemFrameDecoder.java b/src/org/traccar/protocol/TotemFrameDecoder.java index 70dc5db3b..3fa5abc7a 100644 --- a/src/org/traccar/protocol/TotemFrameDecoder.java +++ b/src/org/traccar/protocol/TotemFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,25 +15,26 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; import java.nio.charset.StandardCharsets; -public class TotemFrameDecoder extends FrameDecoder { +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BufferUtil; + +public class TotemFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 10) { return null; } - int beginIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("$$")); + int beginIndex = BufferUtil.indexOf("$$", buf); if (beginIndex == -1) { return null; } else if (beginIndex > buf.readerIndex()) { @@ -49,7 +50,7 @@ public class TotemFrameDecoder extends FrameDecoder { } if (length <= buf.readableBytes()) { - return buf.readBytes(length); + return buf.readRetainedSlice(length); } return null; diff --git a/src/org/traccar/protocol/TotemProtocol.java b/src/org/traccar/protocol/TotemProtocol.java index 1c5cf5b02..c533268cc 100644 --- a/src/org/traccar/protocol/TotemProtocol.java +++ b/src/org/traccar/protocol/TotemProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -37,9 +36,9 @@ public class TotemProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new TotemFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java index 8da188f60..d8caa9766 100644 --- a/src/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/org/traccar/protocol/TotemProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,10 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -243,12 +245,29 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HDOP, parser.nextDouble()); } - position.set(Position.PREFIX_IO + 1, parser.next()); + int io = parser.nextBinInt(); + position.set(Position.KEY_STATUS, io); if (pattern == PATTERN1) { + position.set(Position.KEY_ALARM, BitUtil.check(io, 0) ? Position.ALARM_SOS : null); + position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 4)); + position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 5)); + position.set(Position.PREFIX_IN + 1, BitUtil.check(io, 6)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(io, 7)); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 8)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 9)); position.set(Position.KEY_BATTERY, parser.nextDouble(0) * 0.01); } else { + position.set(Position.KEY_ANTENNA, BitUtil.check(io, 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(io, 1)); + for (int i = 1; i <= 6; i++) { + position.set(Position.PREFIX_IN + i, BitUtil.check(io, 1 + i)); + } + for (int i = 1; i <= 4; i++) { + position.set(Position.PREFIX_OUT + i, BitUtil.check(io, 7 + i)); + } position.set(Position.KEY_BATTERY, parser.nextDouble(0) * 0.1); } + position.set(Position.KEY_POWER, parser.nextDouble(0)); position.set(Position.PREFIX_ADC + 1, parser.next()); @@ -353,7 +372,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; Pattern pattern = PATTERN3; - if (sentence.indexOf("A") == 6) { + if (sentence.charAt(2) == '0') { pattern = PATTERN4; } else if (sentence.contains("$GPRMC")) { pattern = PATTERN1; @@ -392,9 +411,11 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { if (pattern == PATTERN4) { - channel.write("$$0014AA" + sentence.substring(sentence.length() - 6)); + String response = "$$0014AA" + sentence.substring(sentence.length() - 6, sentence.length() - 2); + response += String.format("%02X", Checksum.xor(response)).toUpperCase(); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } else { - channel.write("ACK OK\r\n"); + channel.writeAndFlush(new NetworkMessage("ACK OK\r\n", remoteAddress)); } } diff --git a/src/org/traccar/protocol/Tr20Protocol.java b/src/org/traccar/protocol/Tr20Protocol.java index 8de004be9..629d8b961 100644 --- a/src/org/traccar/protocol/Tr20Protocol.java +++ b/src/org/traccar/protocol/Tr20Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Tr20Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/org/traccar/protocol/Tr20ProtocolDecoder.java index 579d575b0..0c4c12f60 100644 --- a/src/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -60,7 +61,8 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder { Parser parser = new Parser(PATTERN_PING, (String) msg); if (parser.matches()) { if (channel != null) { - channel.write("&&" + parser.next() + "\r\n"); // keep-alive response + channel.writeAndFlush(new NetworkMessage( + "&&" + parser.next() + "\r\n", remoteAddress)); // keep-alive response } return null; } diff --git a/src/org/traccar/protocol/Tr900Protocol.java b/src/org/traccar/protocol/Tr900Protocol.java index 40f287efa..80ad76087 100644 --- a/src/org/traccar/protocol/Tr900Protocol.java +++ b/src/org/traccar/protocol/Tr900Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -34,18 +32,18 @@ public class Tr900Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tr900ProtocolDecoder(Tr900Protocol.this)); diff --git a/src/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/org/traccar/protocol/Tr900ProtocolDecoder.java index 0ce4158e4..8200884ac 100644 --- a/src/org/traccar/protocol/Tr900ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tr900ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 -2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/TrackboxProtocol.java b/src/org/traccar/protocol/TrackboxProtocol.java index c1aa5ac6a..c86870aec 100644 --- a/src/org/traccar/protocol/TrackboxProtocol.java +++ b/src/org/traccar/protocol/TrackboxProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class TrackboxProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/org/traccar/protocol/TrackboxProtocolDecoder.java index 2c113fb76..fff60ae70 100644 --- a/src/org/traccar/protocol/TrackboxProtocolDecoder.java +++ b/src/org/traccar/protocol/TrackboxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -46,9 +47,9 @@ public class TrackboxProtocolDecoder extends BaseProtocolDecoder { .number("(d+)") // satellites .compile(); - private void sendResponse(Channel channel) { + private void sendResponse(Channel channel, SocketAddress remoteAddress) { if (channel != null) { - channel.write("=OK=\r\n"); + channel.writeAndFlush(new NetworkMessage("=OK=\r\n", remoteAddress)); } } @@ -61,7 +62,7 @@ public class TrackboxProtocolDecoder extends BaseProtocolDecoder { if (sentence.startsWith("a=connect")) { String id = sentence.substring(sentence.indexOf("i=") + 2); if (getDeviceSession(channel, remoteAddress, id) != null) { - sendResponse(channel); + sendResponse(channel, remoteAddress); } return null; } @@ -75,7 +76,7 @@ public class TrackboxProtocolDecoder extends BaseProtocolDecoder { if (!parser.matches()) { return null; } - sendResponse(channel); + sendResponse(channel, remoteAddress); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/org/traccar/protocol/TrakMateProtocol.java b/src/org/traccar/protocol/TrakMateProtocol.java index f6d9bf457..506408d65 100644 --- a/src/org/traccar/protocol/TrakMateProtocol.java +++ b/src/org/traccar/protocol/TrakMateProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class TrakMateProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/org/traccar/protocol/TrakMateProtocolDecoder.java index 293c13fad..9fd7af542 100644 --- a/src/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/TramigoFrameDecoder.java b/src/org/traccar/protocol/TramigoFrameDecoder.java index 20992c04b..fae9efecf 100644 --- a/src/org/traccar/protocol/TramigoFrameDecoder.java +++ b/src/org/traccar/protocol/TramigoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,45 +15,32 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; -import java.nio.ByteOrder; - -public class TramigoFrameDecoder extends LengthFieldBasedFrameDecoder { - - public TramigoFrameDecoder() { - super(1024, 6, 2, -8, 0); - } +public class TramigoFrameDecoder extends BaseFrameDecoder { @Override - protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 20) { return null; } - // Swap byte order for legacy protocol + int length; if (buf.getUnsignedByte(buf.readerIndex()) == 0x80) { - int length = buf.readableBytes(); - byte[] bytes = new byte[length]; - buf.getBytes(buf.readerIndex(), bytes); - - ChannelBuffer result = (ChannelBuffer) super.decode( - ctx, channel, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, bytes)); - if (result != null) { - buf.skipBytes(result.readableBytes()); - } - return result; + length = buf.getUnsignedShort(buf.readerIndex() + 6); + } else { + length = buf.getUnsignedShortLE(buf.readerIndex() + 6); + } + + if (length >= buf.readableBytes()) { + return buf.readRetainedSlice(length); } - return super.decode(ctx, channel, buf); + return null; } } diff --git a/src/org/traccar/protocol/TramigoProtocol.java b/src/org/traccar/protocol/TramigoProtocol.java index 28673c97b..74c673967 100644 --- a/src/org/traccar/protocol/TramigoProtocol.java +++ b/src/org/traccar/protocol/TramigoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; -import java.nio.ByteOrder; import java.util.List; public class TramigoProtocol extends BaseProtocol { @@ -31,15 +29,13 @@ public class TramigoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new TramigoFrameDecoder()); pipeline.addLast("objectDecoder", new TramigoProtocolDecoder(TramigoProtocol.this)); } - }; - server.setEndianness(ByteOrder.LITTLE_ENDIAN); - serverList.add(server); + }); } } diff --git a/src/org/traccar/protocol/TramigoProtocolDecoder.java b/src/org/traccar/protocol/TramigoProtocolDecoder.java index 2605346a9..a54a4de68 100644 --- a/src/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/org/traccar/protocol/TramigoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -49,16 +50,18 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; int protocol = buf.readUnsignedByte(); + boolean legacy = protocol == 0x80; + buf.readUnsignedByte(); // version id - int index = buf.readUnsignedShort(); - int type = buf.readUnsignedShort(); + int index = legacy ? buf.readUnsignedShort() : buf.readUnsignedShortLE(); + int type = legacy ? buf.readUnsignedShort() : buf.readUnsignedShortLE(); buf.readUnsignedShort(); // length buf.readUnsignedShort(); // mask buf.readUnsignedShort(); // checksum - long id = buf.readUnsignedInt(); + long id = legacy ? buf.readUnsignedInt() : buf.readUnsignedIntLE(); buf.readUnsignedInt(); // time Position position = new Position(getProtocolName()); @@ -75,36 +78,37 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { // need to send ack? - buf.readUnsignedShort(); // report trigger - buf.readUnsignedShort(); // state flag + buf.readUnsignedShortLE(); // report trigger + buf.readUnsignedShortLE(); // state flag - position.setLatitude(buf.readUnsignedInt() * 0.0000001); - position.setLongitude(buf.readUnsignedInt() * 0.0000001); + position.setLatitude(buf.readUnsignedIntLE() * 0.0000001); + position.setLongitude(buf.readUnsignedIntLE() * 0.0000001); - position.set(Position.KEY_RSSI, buf.readUnsignedShort()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedShort()); - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShort()); - position.set("gpsAntennaStatus", buf.readUnsignedShort()); + position.set(Position.KEY_RSSI, buf.readUnsignedShortLE()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedShortLE()); + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShortLE()); + position.set("gpsAntennaStatus", buf.readUnsignedShortLE()); - position.setSpeed(buf.readUnsignedShort() * 0.194384); - position.setCourse(buf.readUnsignedShort()); + position.setSpeed(buf.readUnsignedShortLE() * 0.194384); + position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE()); - position.set(Position.KEY_CHARGE, buf.readUnsignedShort()); + position.set(Position.KEY_CHARGE, buf.readUnsignedShortLE()); - position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); // parse other data return position; - } else if (protocol == 0x80) { + } else if (legacy) { if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer("gprs,ack," + index, StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer("gprs,ack," + index, StandardCharsets.US_ASCII), remoteAddress)); } String sentence = buf.toString(StandardCharsets.US_ASCII); diff --git a/src/org/traccar/protocol/TrvProtocol.java b/src/org/traccar/protocol/TrvProtocol.java index 348ccd92a..7167ab674 100644 --- a/src/org/traccar/protocol/TrvProtocol.java +++ b/src/org/traccar/protocol/TrvProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class TrvProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java index e0cebc9a5..9c4968974 100644 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/org/traccar/protocol/TrvProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -119,11 +120,11 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { String responseHeader = id + (char) (type.charAt(0) + 1) + type.substring(1); if (type.equals("AP00") && id.equals("IW")) { String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); - channel.write(responseHeader + "," + time + ",0#"); + channel.writeAndFlush(new NetworkMessage(responseHeader + "," + time + ",0#", remoteAddress)); } else if (type.equals("AP14")) { - channel.write(responseHeader + ",0.000,0.000#"); + channel.writeAndFlush(new NetworkMessage(responseHeader + ",0.000,0.000#", remoteAddress)); } else { - channel.write(responseHeader + "#"); + channel.writeAndFlush(new NetworkMessage(responseHeader + "#", remoteAddress)); } } diff --git a/src/org/traccar/protocol/Tt8850Protocol.java b/src/org/traccar/protocol/Tt8850Protocol.java index 79dc031bc..7d3c6a437 100644 --- a/src/org/traccar/protocol/Tt8850Protocol.java +++ b/src/org/traccar/protocol/Tt8850Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class Tt8850Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "$")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java index 0134f4764..46220e143 100644 --- a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/TytanProtocol.java b/src/org/traccar/protocol/TytanProtocol.java index 0c27fb12b..7c424981b 100644 --- a/src/org/traccar/protocol/TytanProtocol.java +++ b/src/org/traccar/protocol/TytanProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class TytanProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new TytanProtocolDecoder(TytanProtocol.this)); } }); diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java index a65ad4cfc..6788fd7b9 100644 --- a/src/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/org/traccar/protocol/TytanProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -36,7 +38,7 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void decodeExtraData(Position position, ChannelBuffer buf, int end) { + private void decodeExtraData(Position position, ByteBuf buf, int end) { while (buf.readerIndex() < end) { int type = buf.readUnsignedByte(); @@ -73,10 +75,10 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { position.set("antihijack", buf.readUnsignedByte()); break; case 9: - position.set("unauthorized", ChannelBuffers.hexDump(buf.readBytes(8))); + position.set("unauthorized", ByteBufUtil.hexDump(buf.readSlice(8))); break; case 10: - position.set("authorized", ChannelBuffers.hexDump(buf.readBytes(8))); + position.set("authorized", ByteBufUtil.hexDump(buf.readSlice(8))); break; case 24: for (int i = 0; i < length / 2; i++) { @@ -124,16 +126,15 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // protocol buf.readUnsignedShort(); // length int index = buf.readUnsignedByte() >> 3; if (channel != null) { - ChannelBuffer response = ChannelBuffers.copiedBuffer( - "^" + index, StandardCharsets.US_ASCII); - channel.write(response, remoteAddress); + ByteBuf response = Unpooled.copiedBuffer("^" + index, StandardCharsets.US_ASCII); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } String id = String.valueOf(buf.readUnsignedInt()); diff --git a/src/org/traccar/protocol/TzoneProtocol.java b/src/org/traccar/protocol/TzoneProtocol.java index 38d5b139a..21a304402 100644 --- a/src/org/traccar/protocol/TzoneProtocol.java +++ b/src/org/traccar/protocol/TzoneProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; + import java.util.List; public class TzoneProtocol extends BaseProtocol { @@ -31,9 +31,9 @@ public class TzoneProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); pipeline.addLast("objectDecoder", new TzoneProtocolDecoder(TzoneProtocol.this)); } diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index 984891bb6..6f6ff3878 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -57,7 +57,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeCards(Position position, ChannelBuffer buf) { + private void decodeCards(Position position, ByteBuf buf) { int index = 1; for (int i = 0; i < 4; i++) { @@ -77,7 +77,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { length += 1; } - String num = ChannelBuffers.hexDump(buf.readBytes(length / 2)); + String num = ByteBufUtil.hexDump(buf.readSlice(length / 2)); if (odd) { num = num.substring(1); @@ -92,7 +92,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - private void decodePassengers(Position position, ChannelBuffer buf) { + private void decodePassengers(Position position, ByteBuf buf) { int blockLength = buf.readUnsignedShort(); int blockEnd = buf.readerIndex() + blockLength; @@ -112,7 +112,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(2); // header buf.readUnsignedShort(); // length @@ -122,7 +122,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { int hardware = buf.readUnsignedShort(); long firmware = buf.readUnsignedInt(); - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; diff --git a/src/org/traccar/protocol/UlbotechFrameDecoder.java b/src/org/traccar/protocol/UlbotechFrameDecoder.java index 8e7b497c5..f141dc9b7 100644 --- a/src/org/traccar/protocol/UlbotechFrameDecoder.java +++ b/src/org/traccar/protocol/UlbotechFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,19 +15,18 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class UlbotechFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class UlbotechFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 2) { return null; @@ -37,7 +36,7 @@ public class UlbotechFrameDecoder extends FrameDecoder { int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0xF8); if (index != -1) { - ChannelBuffer result = ChannelBuffers.buffer(index + 1 - buf.readerIndex()); + ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); while (buf.readerIndex() <= index) { int b = buf.readUnsignedByte(); @@ -60,7 +59,7 @@ public class UlbotechFrameDecoder extends FrameDecoder { int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); if (index != -1) { - return buf.readBytes(index + 1 - buf.readerIndex()); + return buf.readRetainedSlice(index + 1 - buf.readerIndex()); } } diff --git a/src/org/traccar/protocol/UlbotechProtocol.java b/src/org/traccar/protocol/UlbotechProtocol.java index 40f4594a5..7d6d95706 100644 --- a/src/org/traccar/protocol/UlbotechProtocol.java +++ b/src/org/traccar/protocol/UlbotechProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class UlbotechProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new UlbotechFrameDecoder()); pipeline.addLast("objectDecoder", new UlbotechProtocolDecoder(UlbotechProtocol.this)); } diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java index 5499518a1..ed4695a44 100644 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -15,11 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; @@ -58,18 +60,18 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { private static final short DATA_RFID = 0x0E; private static final short DATA_EVENT = 0x10; - private void decodeObd(Position position, ChannelBuffer buf, int length) { + private void decodeObd(Position position, ByteBuf buf, int length) { int end = buf.readerIndex() + length; while (buf.readerIndex() < end) { int parameterLength = buf.getUnsignedByte(buf.readerIndex()) >> 4; int mode = buf.readUnsignedByte() & 0x0F; - position.add(ObdDecoder.decode(mode, ChannelBuffers.hexDump(buf.readBytes(parameterLength - 1)))); + position.add(ObdDecoder.decode(mode, ByteBufUtil.hexDump(buf.readSlice(parameterLength - 1)))); } } - private void decodeJ1708(Position position, ChannelBuffer buf, int length) { + private void decodeJ1708(Position position, ByteBuf buf, int length) { int end = buf.readerIndex() + length; @@ -81,14 +83,14 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { if (type == 3) { id += 256; } - String value = ChannelBuffers.hexDump(buf.readBytes(len - 1)); + String value = ByteBufUtil.hexDump(buf.readSlice(len - 1)); if (type == 2 || type == 3) { position.set("pid" + id, value); } } } - private void decodeDriverBehavior(Position position, ChannelBuffer buf) { + private void decodeDriverBehavior(Position position, ByteBuf buf) { int value = buf.readUnsignedByte(); @@ -137,7 +139,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { return null; } - private void decodeAdc(Position position, ChannelBuffer buf, int length) { + private void decodeAdc(Position position, ByteBuf buf, int length) { for (int i = 0; i < length / 2; i++) { int value = buf.readUnsignedShort(); int id = BitUtil.from(value, 12); @@ -198,13 +200,13 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBinary(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private Object decodeBinary(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedByte(); // header buf.readUnsignedByte(); // version buf.readUnsignedByte(); // type - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { @@ -294,7 +296,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { break; case DATA_CANBUS: - position.set("can", ChannelBuffers.hexDump(buf.readBytes(length))); + position.set("can", ByteBufUtil.hexDump(buf.readSlice(length))); break; case DATA_J1708: @@ -302,12 +304,12 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { break; case DATA_VIN: - position.set(Position.KEY_VIN, buf.readBytes(length).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); break; case DATA_RFID: position.set(Position.KEY_DRIVER_UNIQUE_ID, - buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII)); + buf.readSlice(length - 1).toString(StandardCharsets.US_ASCII)); position.set("authorized", buf.readUnsignedByte() != 0); break; @@ -337,28 +339,28 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getUnsignedByte(buf.readerIndex()) == 0xF8) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + ByteBuf response = Unpooled.buffer(); response.writeByte(0xF8); response.writeByte(DATA_GPS); response.writeByte(0xFE); response.writeShort(buf.getShort(response.writerIndex() - 1 - 2)); - response.writeShort(Checksum.crc16(Checksum.CRC16_XMODEM, response.toByteBuffer(1, 4))); + response.writeShort(Checksum.crc16(Checksum.CRC16_XMODEM, response.nioBuffer(1, 4))); response.writeByte(0xF8); - channel.write(response); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return decodeBinary(channel, remoteAddress, buf); } else { if (channel != null) { - channel.write(ChannelBuffers.copiedBuffer(String.format("*TS01,ACK:%04X#", - Checksum.crc16(Checksum.CRC16_XMODEM, buf.toByteBuffer(1, buf.writerIndex() - 2))), - StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage(Unpooled.copiedBuffer(String.format("*TS01,ACK:%04X#", + Checksum.crc16(Checksum.CRC16_XMODEM, buf.nioBuffer(1, buf.writerIndex() - 2))), + StandardCharsets.US_ASCII), remoteAddress)); } return decodeText(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)); diff --git a/src/org/traccar/protocol/UproProtocol.java b/src/org/traccar/protocol/UproProtocol.java index c00f859ee..832121ec1 100644 --- a/src/org/traccar/protocol/UproProtocol.java +++ b/src/org/traccar/protocol/UproProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -32,9 +31,9 @@ public class UproProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new UproProtocolDecoder(UproProtocol.this)); diff --git a/src/org/traccar/protocol/UproProtocolDecoder.java b/src/org/traccar/protocol/UproProtocolDecoder.java index 28f3d0249..1c2944a6c 100644 --- a/src/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/org/traccar/protocol/UproProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -92,7 +93,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getByte(buf.readerIndex()) != '*') { throw new ParseException(null, 0); @@ -102,7 +103,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { if (headerIndex < 0) { headerIndex = buf.writerIndex(); } - String header = buf.readBytes(headerIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); + String header = buf.readSlice(headerIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); Parser parser = new Parser(PATTERN_HEADER, header); if (!parser.matches()) { @@ -123,10 +124,10 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { String subtype = parser.next(); if (reply && channel != null) { - channel.write("*MG20Y" + type + subtype + "#"); + channel.writeAndFlush(new NetworkMessage("*MG20Y" + type + subtype + "#", remoteAddress)); } - while (buf.readable()) { + while (buf.isReadable()) { buf.readByte(); // skip delimiter @@ -137,7 +138,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { delimiterIndex = buf.writerIndex(); } - ChannelBuffer data = buf.readBytes(delimiterIndex - buf.readerIndex()); + ByteBuf data = buf.readSlice(delimiterIndex - buf.readerIndex()); switch (dataType) { case 'A': @@ -148,7 +149,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { break; case 'C': long odometer = 0; - while (data.readable()) { + while (data.isReadable()) { odometer <<= 4; odometer += data.readByte() - (byte) '0'; } @@ -156,19 +157,19 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { break; case 'P': position.setNetwork(new Network(CellTower.from( - Integer.parseInt(data.readBytes(4).toString(StandardCharsets.US_ASCII)), - Integer.parseInt(data.readBytes(4).toString(StandardCharsets.US_ASCII)), - Integer.parseInt(data.readBytes(4).toString(StandardCharsets.US_ASCII), 16), - Integer.parseInt(data.readBytes(4).toString(StandardCharsets.US_ASCII), 16)))); + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)), + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)), + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII), 16), + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII), 16)))); break; case 'Q': - position.set("obd-pid", ChannelBuffers.hexDump(data)); + position.set("obd-pid", ByteBufUtil.hexDump(data)); break; case 'R': - position.set("odb-travel", ChannelBuffers.hexDump(data)); + position.set("odb-travel", ByteBufUtil.hexDump(data)); break; case 'S': - position.set("obd-traffic", ChannelBuffers.hexDump(data)); + position.set("obd-traffic", ByteBufUtil.hexDump(data)); break; default: break; diff --git a/src/org/traccar/protocol/V680Protocol.java b/src/org/traccar/protocol/V680Protocol.java index 98c64830b..eb9111578 100644 --- a/src/org/traccar/protocol/V680Protocol.java +++ b/src/org/traccar/protocol/V680Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,11 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -34,18 +32,18 @@ public class V680Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder 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/V680ProtocolDecoder.java b/src/org/traccar/protocol/V680ProtocolDecoder.java index caa06a863..05095e8ba 100644 --- a/src/org/traccar/protocol/V680ProtocolDecoder.java +++ b/src/org/traccar/protocol/V680ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/VisiontekProtocol.java b/src/org/traccar/protocol/VisiontekProtocol.java index c6dd09562..897c7e6f7 100644 --- a/src/org/traccar/protocol/VisiontekProtocol.java +++ b/src/org/traccar/protocol/VisiontekProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ 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 io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class VisiontekProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java index 33c555c6b..57ccb5100 100644 --- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/Vt200FrameDecoder.java b/src/org/traccar/protocol/Vt200FrameDecoder.java index adde12118..0fd83e715 100644 --- a/src/org/traccar/protocol/Vt200FrameDecoder.java +++ b/src/org/traccar/protocol/Vt200FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,22 +15,23 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class Vt200FrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class Vt200FrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ')') + 1; if (endIndex > 0) { - ChannelBuffer frame = ChannelBuffers.dynamicBuffer(); + ByteBuf frame = Unpooled.buffer(); while (buf.readerIndex() < endIndex) { int b = buf.readByte(); diff --git a/src/org/traccar/protocol/Vt200Protocol.java b/src/org/traccar/protocol/Vt200Protocol.java index 59c61cb61..b227020c2 100644 --- a/src/org/traccar/protocol/Vt200Protocol.java +++ b/src/org/traccar/protocol/Vt200Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class Vt200Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new Vt200FrameDecoder()); pipeline.addLast("objectDecoder", new Vt200ProtocolDecoder(Vt200Protocol.this)); } diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index d08107b16..d5035bd5c 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,9 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; @@ -42,7 +42,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes * 0.0001 / 60; } - protected Date decodeDate(ChannelBuffer buf) { + protected Date decodeDate(ByteBuf buf) { DateBuilder dateBuilder = new DateBuilder() .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); @@ -53,11 +53,11 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(1); // header - String id = ChannelBuffers.hexDump(buf.readBytes(6)); + String id = ByteBufUtil.hexDump(buf.readSlice(6)); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; diff --git a/src/org/traccar/protocol/VtfmsFrameDecoder.java b/src/org/traccar/protocol/VtfmsFrameDecoder.java index 2e6033fcc..62a189960 100644 --- a/src/org/traccar/protocol/VtfmsFrameDecoder.java +++ b/src/org/traccar/protocol/VtfmsFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,22 +15,23 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.traccar.BaseFrameDecoder; -public class VtfmsFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class VtfmsFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ')'); if (endIndex > 0) { endIndex += 1 + 3; if (buf.writerIndex() >= endIndex) { - return buf.readBytes(endIndex - buf.readerIndex()); + return buf.readRetainedSlice(endIndex - buf.readerIndex()); } } diff --git a/src/org/traccar/protocol/VtfmsProtocol.java b/src/org/traccar/protocol/VtfmsProtocol.java index 61e0bf2b9..dee72aaa8 100644 --- a/src/org/traccar/protocol/VtfmsProtocol.java +++ b/src/org/traccar/protocol/VtfmsProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import io.netty.handler.codec.string.StringDecoder; + import java.util.List; public class VtfmsProtocol extends BaseProtocol { @@ -32,17 +31,17 @@ public class VtfmsProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new VtfmsFrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new VtfmsProtocolDecoder(VtfmsProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new VtfmsProtocolDecoder(VtfmsProtocol.this)); } diff --git a/src/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/org/traccar/protocol/VtfmsProtocolDecoder.java index dc2171022..5e5e5c9b5 100644 --- a/src/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; @@ -133,7 +133,7 @@ public class VtfmsProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.set(Position.KEY_HOURS, parser.nextInt()); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(parser.nextInt())); position.set("idleHours", parser.nextInt()); position.set(Position.KEY_ODOMETER, parser.nextInt() * 100); position.set(Position.KEY_CHARGE, parser.next().equals("1")); diff --git a/src/org/traccar/protocol/WatchFrameDecoder.java b/src/org/traccar/protocol/WatchFrameDecoder.java index 9adea2843..1e2f0cea3 100644 --- a/src/org/traccar/protocol/WatchFrameDecoder.java +++ b/src/org/traccar/protocol/WatchFrameDecoder.java @@ -15,19 +15,20 @@ */ 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.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; import java.nio.charset.StandardCharsets; -public class WatchFrameDecoder extends FrameDecoder { +import org.traccar.BaseFrameDecoder; + +public class WatchFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { int idIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') + 1; if (idIndex <= 0) { @@ -37,11 +38,6 @@ public class WatchFrameDecoder extends FrameDecoder { int lengthIndex = buf.indexOf(idIndex, buf.writerIndex(), (byte) '*') + 1; if (lengthIndex <= 0) { return null; - } else if (lengthIndex - idIndex > 10 + 1) { - lengthIndex = buf.indexOf(lengthIndex, buf.writerIndex(), (byte) '*') + 1; - if (lengthIndex <= 0) { - return null; - } } int payloadIndex = buf.indexOf(lengthIndex, buf.writerIndex(), (byte) '*'); @@ -49,10 +45,19 @@ public class WatchFrameDecoder extends FrameDecoder { return null; } + if (payloadIndex + 5 < buf.writerIndex() && buf.getByte(payloadIndex + 5) == '*' + && buf.toString(payloadIndex + 1, 4, StandardCharsets.US_ASCII).matches("\\p{XDigit}+")) { + lengthIndex = payloadIndex + 1; + payloadIndex = buf.indexOf(lengthIndex, buf.writerIndex(), (byte) '*'); + if (payloadIndex < 0) { + return null; + } + } + int length = Integer.parseInt( buf.toString(lengthIndex, payloadIndex - lengthIndex, StandardCharsets.US_ASCII), 16); if (buf.readableBytes() >= payloadIndex + 1 + length + 1) { - ChannelBuffer frame = ChannelBuffers.dynamicBuffer(); + ByteBuf frame = Unpooled.buffer(); int endIndex = buf.readerIndex() + payloadIndex + 1 + length + 1; while (buf.readerIndex() < endIndex) { byte b = buf.readByte(); diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index 2be2dc9ae..6f9a4a882 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,13 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class WatchProtocol extends BaseProtocol { @@ -47,9 +47,9 @@ public class WatchProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new WatchFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new WatchProtocolEncoder()); diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index c57279296..4e5d8c377 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -15,11 +15,12 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -60,14 +61,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { .expression("(.*)") // cell and wifi .compile(); - private void sendResponse(Channel channel, String manufacturer, String id, String index, String content) { + private void sendResponse(Channel channel, String id, String index, String content) { if (channel != null) { if (index != null) { - channel.write(String.format( - "[%s*%s*%s*%04x*%s]", manufacturer, id, index, content.length(), content)); + channel.writeAndFlush(new NetworkMessage(String.format("[%s*%s*%s*%04x*%s]", + manufacturer, id, index, content.length(), content), channel.remoteAddress())); } else { - channel.write(String.format( - "[%s*%s*%04x*%s]", manufacturer, id, content.length(), content)); + channel.writeAndFlush(new NetworkMessage(String.format("[%s*%s*%04x*%s]", + manufacturer, id, content.length(), content), channel.remoteAddress())); } } } @@ -161,18 +162,29 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return position; } + private boolean hasIndex; + private String manufacturer; + + public boolean getHasIndex() { + return hasIndex; + } + + public String getManufacturer() { + return manufacturer; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; buf.skipBytes(1); // header - String manufacturer = buf.readBytes(2).toString(StandardCharsets.US_ASCII); + manufacturer = buf.readSlice(2).toString(StandardCharsets.US_ASCII); buf.skipBytes(1); // delimiter - int idLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') - buf.readerIndex(); - String id = buf.readBytes(idLength).toString(StandardCharsets.US_ASCII); + int idIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*'); + String id = buf.readSlice(idIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; @@ -181,9 +193,12 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(1); // delimiter String index = null; - if (idLength > 10) { + int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*'); + if (contentIndex + 5 < buf.writerIndex() && buf.getByte(contentIndex + 5) == '*' + && buf.toString(contentIndex + 1, 4, StandardCharsets.US_ASCII).matches("\\p{XDigit}+")) { int indexLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') - buf.readerIndex(); - index = buf.readBytes(indexLength).toString(StandardCharsets.US_ASCII); + hasIndex = true; + index = buf.readSlice(indexLength).toString(StandardCharsets.US_ASCII); buf.skipBytes(1); // delimiter } @@ -192,12 +207,12 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { buf.writerIndex(buf.writerIndex() - 1); // ignore ending - int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); + contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); if (contentIndex < 0) { contentIndex = buf.writerIndex(); } - String type = buf.readBytes(contentIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); + String type = buf.readSlice(contentIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); if (contentIndex < buf.writerIndex()) { buf.readerIndex(contentIndex + 1); @@ -205,13 +220,13 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { if (type.equals("INIT")) { - sendResponse(channel, manufacturer, id, index, "INIT,1"); + sendResponse(channel, id, index, "INIT,1"); } else if (type.equals("LK")) { - sendResponse(channel, manufacturer, id, index, "LK"); + sendResponse(channel, id, index, "LK"); - if (buf.readable()) { + if (buf.isReadable()) { String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); if (values.length >= 3) { Position position = new Position(getProtocolName()); @@ -228,19 +243,24 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (type.equals("UD") || type.equals("UD2") || type.equals("UD3") || type.equals("AL") || type.equals("WT")) { + Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); + if (type.equals("AL")) { - sendResponse(channel, manufacturer, id, index, "AL"); + if (position != null) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + sendResponse(channel, id, index, "AL"); } - return decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); + return position; } else if (type.equals("TKQ")) { - sendResponse(channel, manufacturer, id, index, "TKQ"); + sendResponse(channel, id, index, "TKQ"); } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) { - if (buf.readable()) { + if (buf.isReadable()) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -254,7 +274,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { position.set("pressureHigh", values[valueIndex++]); position.set("pressureLow", values[valueIndex++]); } - position.set("pulse", values[valueIndex]); + position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex])); return position; diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index 5206fbf10..b2d35e702 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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. @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import io.netty.channel.Channel; import org.traccar.StringProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.helper.Log; @@ -41,12 +42,27 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin return null; } + protected String formatCommand(Channel channel, Command command, String format, String... keys) { + + boolean hasIndex = false; + String manufacturer = "CS"; + if (channel != null) { + WatchProtocolDecoder decoder = channel.pipeline().get(WatchProtocolDecoder.class); + if (decoder != null) { + hasIndex = decoder.getHasIndex(); + manufacturer = decoder.getManufacturer(); + } + } - @Override - protected String formatCommand(Command command, String format, String... keys) { String content = formatCommand(command, format, this, keys); - return String.format("[CS*%s*%04x*%s]", - getUniqueId(command.getDeviceId()), content.length(), content); + + if (hasIndex) { + return String.format("[%s*%s*0001*%04x*%s]", + manufacturer, getUniqueId(command.getDeviceId()), content.length(), content); + } else { + return String.format("[%s*%s*%04x*%s]", + manufacturer, getUniqueId(command.getDeviceId()), content.length(), content); + } } private int getEnableFlag(Command command) { @@ -96,37 +112,37 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin } @Override - protected Object encodeCommand(Command command) { + protected Object encodeCommand(Channel channel, Command command) { switch (command.getType()) { case Command.TYPE_CUSTOM: - return formatCommand(command, command.getString(Command.KEY_DATA)); + return formatCommand(channel, command, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "RG"); + return formatCommand(channel, command, "RG"); case Command.TYPE_SOS_NUMBER: - return formatCommand(command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE); + return formatCommand(channel, command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE); case Command.TYPE_ALARM_SOS: - return formatCommand(command, "SOSSMS," + getEnableFlag(command)); + return formatCommand(channel, command, "SOSSMS," + getEnableFlag(command)); case Command.TYPE_ALARM_BATTERY: - return formatCommand(command, "LOWBAT," + getEnableFlag(command)); + return formatCommand(channel, command, "LOWBAT," + getEnableFlag(command)); case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "RESET"); + return formatCommand(channel, command, "RESET"); case Command.TYPE_ALARM_REMOVE: - return formatCommand(command, "REMOVE," + getEnableFlag(command)); + return formatCommand(channel, command, "REMOVE," + getEnableFlag(command)); case Command.TYPE_SILENCE_TIME: - return formatCommand(command, "SILENCETIME,{%s}", Command.KEY_DATA); + return formatCommand(channel, command, "SILENCETIME,{%s}", Command.KEY_DATA); case Command.TYPE_ALARM_CLOCK: - return formatCommand(command, "REMIND,{%s}", Command.KEY_DATA); + return formatCommand(channel, command, "REMIND,{%s}", Command.KEY_DATA); case Command.TYPE_SET_PHONEBOOK: - return formatCommand(command, "PHB,{%s}", Command.KEY_DATA); + return formatCommand(channel, command, "PHB,{%s}", Command.KEY_DATA); case Command.TYPE_VOICE_MESSAGE: - return formatCommand(command, "TK," + getBinaryData(command)); + return formatCommand(channel, command, "TK," + getBinaryData(command)); case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "UPLOAD,{%s}", Command.KEY_FREQUENCY); + return formatCommand(channel, command, "UPLOAD,{%s}", Command.KEY_FREQUENCY); case Command.TYPE_SET_TIMEZONE: - return formatCommand(command, "LZ,,{%s}", Command.KEY_TIMEZONE); + return formatCommand(channel, command, "LZ,,{%s}", Command.KEY_TIMEZONE); case Command.TYPE_SET_INDICATOR: - return formatCommand(command, "FLOWER,{%s}", Command.KEY_DATA); + return formatCommand(channel, command, "FLOWER,{%s}", Command.KEY_DATA); default: Log.warning(new UnsupportedOperationException(command.getType())); break; diff --git a/src/org/traccar/protocol/WialonProtocol.java b/src/org/traccar/protocol/WialonProtocol.java index 02da154e2..119d9899b 100644 --- a/src/org/traccar/protocol/WialonProtocol.java +++ b/src/org/traccar/protocol/WialonProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,16 +15,16 @@ */ package org.traccar.protocol; -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.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; + import java.nio.charset.StandardCharsets; import java.util.List; @@ -41,9 +41,9 @@ public class WialonProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(4 * 1024)); pipeline.addLast("stringEncoder", new StringEncoder()); boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java index 5bc3e9972..805c12cf9 100644 --- a/src/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/org/traccar/protocol/WialonProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -57,14 +58,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { .groupEnd("?") .compile(); - private void sendResponse(Channel channel, String prefix, Integer number) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String prefix, Integer number) { if (channel != null) { StringBuilder response = new StringBuilder(prefix); if (number != null) { response.append(number); } response.append("\r\n"); - channel.write(response.toString()); + channel.writeAndFlush(new NetworkMessage(response.toString(), remoteAddress)); } } @@ -140,12 +141,12 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { String imei = values[0].indexOf('.') >= 0 ? values[1] : values[0]; DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null) { - sendResponse(channel, "#AL#", 1); + sendResponse(channel, remoteAddress, "#AL#", 1); } } else if (sentence.startsWith("#P#")) { - sendResponse(channel, "#AP#", null); // heartbeat + sendResponse(channel, remoteAddress, "#AP#", null); // heartbeat } else if (sentence.startsWith("#SD#") || sentence.startsWith("#D#")) { @@ -153,7 +154,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, sentence.substring(sentence.indexOf('#', 1) + 1)); if (position != null) { - sendResponse(channel, "#AD#", 1); + sendResponse(channel, remoteAddress, "#AD#", 1); return position; } @@ -170,7 +171,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } } - sendResponse(channel, "#AB#", messages.length); + sendResponse(channel, remoteAddress, "#AB#", messages.length); if (!positions.isEmpty()) { return positions; } @@ -183,7 +184,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date()); position.setValid(false); position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf('#', 1) + 1)); - sendResponse(channel, "#AM#", 1); + sendResponse(channel, remoteAddress, "#AM#", 1); return position; } } diff --git a/src/org/traccar/protocol/WondexFrameDecoder.java b/src/org/traccar/protocol/WondexFrameDecoder.java index db65ff80f..39d83d761 100644 --- a/src/org/traccar/protocol/WondexFrameDecoder.java +++ b/src/org/traccar/protocol/WondexFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,19 +15,21 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import org.traccar.BaseFrameDecoder; +import org.traccar.NetworkMessage; +import org.traccar.helper.BufferUtil; -public class WondexFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class WondexFrameDecoder extends BaseFrameDecoder { private static final int KEEP_ALIVE_LENGTH = 8; @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < KEEP_ALIVE_LENGTH) { return null; @@ -36,17 +38,18 @@ public class WondexFrameDecoder extends FrameDecoder { if (buf.getUnsignedByte(buf.readerIndex()) == 0xD0) { // Send response - ChannelBuffer frame = buf.readBytes(KEEP_ALIVE_LENGTH); + ByteBuf frame = buf.readRetainedSlice(KEEP_ALIVE_LENGTH); if (channel != null) { - channel.write(frame); + frame.retain(); + channel.writeAndFlush(new NetworkMessage(frame, channel.remoteAddress())); } return frame; } else { - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("\r\n")); + int index = BufferUtil.indexOf("\r\n", buf); if (index != -1) { - ChannelBuffer frame = buf.readBytes(index - buf.readerIndex()); + ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex()); buf.skipBytes(2); return frame; } diff --git a/src/org/traccar/protocol/WondexProtocol.java b/src/org/traccar/protocol/WondexProtocol.java index ef25265aa..a43c8b06a 100644 --- a/src/org/traccar/protocol/WondexProtocol.java +++ b/src/org/traccar/protocol/WondexProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,13 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class WondexProtocol extends BaseProtocol { @@ -41,18 +40,18 @@ public class WondexProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new WondexFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new WondexProtocolEncoder()); pipeline.addLast("objectDecoder", new WondexProtocolDecoder(WondexProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new WondexProtocolEncoder()); pipeline.addLast("objectDecoder", new WondexProtocolDecoder(WondexProtocol.this)); diff --git a/src/org/traccar/protocol/WondexProtocolDecoder.java b/src/org/traccar/protocol/WondexProtocolDecoder.java index a0fa436e4..7845cb26a 100644 --- a/src/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/org/traccar/protocol/WondexProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; @@ -60,7 +60,7 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; if (buf.getUnsignedByte(0) == 0xD0) { diff --git a/src/org/traccar/protocol/XexunFrameDecoder.java b/src/org/traccar/protocol/XexunFrameDecoder.java index 801fb4d59..114e94061 100644 --- a/src/org/traccar/protocol/XexunFrameDecoder.java +++ b/src/org/traccar/protocol/XexunFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,31 +15,32 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.traccar.helper.StringFinder; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BufferUtil; -public class XexunFrameDecoder extends FrameDecoder { +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; + +public class XexunFrameDecoder extends BaseFrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { if (buf.readableBytes() < 80) { return null; } - int beginIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("GPRMC")); + int beginIndex = BufferUtil.indexOf("GPRMC", buf); if (beginIndex == -1) { - beginIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), new StringFinder("GNRMC")); + beginIndex = BufferUtil.indexOf("GNRMC", buf); if (beginIndex == -1) { return null; } } - int identifierIndex = buf.indexOf(beginIndex, buf.writerIndex(), new StringFinder("imei:")); + int identifierIndex = BufferUtil.indexOf("imei:", buf, beginIndex, buf.writerIndex()); if (identifierIndex == -1) { return null; } @@ -51,7 +52,7 @@ public class XexunFrameDecoder extends FrameDecoder { buf.skipBytes(beginIndex - buf.readerIndex()); - return buf.readBytes(endIndex - beginIndex + 1); + return buf.readRetainedSlice(endIndex - beginIndex + 1); } } diff --git a/src/org/traccar/protocol/XexunProtocol.java b/src/org/traccar/protocol/XexunProtocol.java index b90cbfaaf..11e0e0761 100644 --- a/src/org/traccar/protocol/XexunProtocol.java +++ b/src/org/traccar/protocol/XexunProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,16 +15,16 @@ */ package org.traccar.protocol; -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.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class XexunProtocol extends BaseProtocol { @@ -38,9 +38,9 @@ public class XexunProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { boolean full = Context.getConfig().getBoolean(getName() + ".extended"); if (full) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); // tracker bug \n\r diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index a06a86021..42699c272 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 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. @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; diff --git a/src/org/traccar/protocol/XirgoProtocol.java b/src/org/traccar/protocol/XirgoProtocol.java index 13aa8fde1..18017bcdb 100644 --- a/src/org/traccar/protocol/XirgoProtocol.java +++ b/src/org/traccar/protocol/XirgoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,16 +15,15 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.model.Command; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class XirgoProtocol extends BaseProtocol { @@ -37,9 +36,9 @@ public class XirgoProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); @@ -47,9 +46,9 @@ public class XirgoProtocol extends BaseProtocol { pipeline.addLast("objectDecoder", new XirgoProtocolDecoder(XirgoProtocol.this)); } }); - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new XirgoProtocolEncoder()); diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java index 461503af1..878715e40 100644 --- a/src/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/org/traccar/protocol/XirgoProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; @@ -232,7 +232,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_OUT + 1, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble()); - position.set(Position.KEY_HOURS, parser.nextInt()); + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(parser.nextInt())); position.set("oilPressure", parser.nextInt()); position.set("oilLevel", parser.nextInt()); position.set("oilTemp", parser.nextInt()); diff --git a/src/org/traccar/protocol/Xt013Protocol.java b/src/org/traccar/protocol/Xt013Protocol.java index ad3e24df0..8e43e8f0b 100644 --- a/src/org/traccar/protocol/Xt013Protocol.java +++ b/src/org/traccar/protocol/Xt013Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,14 +15,14 @@ */ package org.traccar.protocol; -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.PipelineBuilder; import org.traccar.TrackerServer; +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; + import java.util.List; public class Xt013Protocol extends BaseProtocol { @@ -33,9 +33,9 @@ public class Xt013Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); diff --git a/src/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/org/traccar/protocol/Xt013ProtocolDecoder.java index a92afd778..fda7c59ea 100644 --- a/src/org/traccar/protocol/Xt013ProtocolDecoder.java +++ b/src/org/traccar/protocol/Xt013ProtocolDecoder.java @@ -15,7 +15,7 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.Parser; diff --git a/src/org/traccar/protocol/Xt2400Protocol.java b/src/org/traccar/protocol/Xt2400Protocol.java index 0c5e9cd4c..08b281554 100644 --- a/src/org/traccar/protocol/Xt2400Protocol.java +++ b/src/org/traccar/protocol/Xt2400Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,9 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -30,9 +29,9 @@ public class Xt2400Protocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + serverList.add(new TrackerServer(true, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("objectDecoder", new Xt2400ProtocolDecoder(Xt2400Protocol.this)); } }); diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java index 1be943e98..a01a64b5b 100644 --- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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. @@ -15,8 +15,8 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; @@ -103,7 +103,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; byte[] format = null; if (formats.size() > 1) { @@ -174,10 +174,10 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(buf.readUnsignedShort())); break; case 0x65: - position.set(Position.KEY_VIN, buf.readBytes(17).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); break; case 0x73: - position.set(Position.KEY_VERSION_FW, buf.readBytes(16).toString(StandardCharsets.US_ASCII).trim()); + position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); break; default: buf.skipBytes(getTagLength(tag)); diff --git a/src/org/traccar/protocol/YwtProtocol.java b/src/org/traccar/protocol/YwtProtocol.java index 412365ecb..c026fc61a 100644 --- a/src/org/traccar/protocol/YwtProtocol.java +++ b/src/org/traccar/protocol/YwtProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 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. @@ -15,12 +15,11 @@ */ package org.traccar.protocol; -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 io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import java.util.List; @@ -33,9 +32,9 @@ public class YwtProtocol extends BaseProtocol { @Override public void initTrackerServers(List<TrackerServer> serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + serverList.add(new TrackerServer(false, getName()) { @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); diff --git a/src/org/traccar/protocol/YwtProtocolDecoder.java b/src/org/traccar/protocol/YwtProtocolDecoder.java index 3182b838d..4c71b0aea 100644 --- a/src/org/traccar/protocol/YwtProtocolDecoder.java +++ b/src/org/traccar/protocol/YwtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2014 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 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. @@ -15,9 +15,10 @@ */ package org.traccar.protocol; -import org.jboss.netty.channel.Channel; +import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; @@ -67,7 +68,7 @@ public class YwtProtocolDecoder extends BaseProtocolDecoder { end = sentence.length(); } - channel.write("%AT+SN=" + sentence.substring(start, end)); + channel.writeAndFlush(new NetworkMessage("%AT+SN=" + sentence.substring(start, end), remoteAddress)); return null; } @@ -104,7 +105,7 @@ public class YwtProtocolDecoder extends BaseProtocolDecoder { // Send response if ((type.equals("KP") || type.equals("EP")) && channel != null) { - channel.write("%AT+" + type + "=" + reportId + "\r\n"); + channel.writeAndFlush(new NetworkMessage("%AT+" + type + "=" + reportId + "\r\n", remoteAddress)); } return position; diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 7cb6ef6eb..66d9e708d 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -1,6 +1,6 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; +import org.traccar.model.Maintenance; import org.traccar.reports.model.DeviceReport; public final class Events { @@ -51,7 +52,10 @@ public final class Events { for (Event event : events) { if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); - if (geofenceId == 0 || Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) { + long maintenanceId = event.getMaintenanceId(); + if ((geofenceId == 0 || Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) + && (maintenanceId == 0 + || Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId))) { result.add(event); } } @@ -67,6 +71,7 @@ public final class Events { ArrayList<DeviceReport> devicesEvents = new ArrayList<>(); ArrayList<String> sheetNames = new ArrayList<>(); HashMap<Long, String> geofenceNames = new HashMap<>(); + HashMap<Long, String> maintenanceNames = new HashMap<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection<Event> events = Context.getDataManager().getEvents(deviceId, from, to); @@ -75,6 +80,7 @@ public final class Events { Event event = iterator.next(); if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); + long maintenanceId = event.getMaintenanceId(); if (geofenceId != 0) { if (Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) { Geofence geofence = Context.getGeofenceManager().getById(geofenceId); @@ -84,6 +90,15 @@ public final class Events { } else { iterator.remove(); } + } else if (maintenanceId != 0) { + if (Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId)) { + Maintenance maintenance = Context.getMaintenancesManager().getById(maintenanceId); + if (maintenance != null) { + maintenanceNames.put(maintenanceId, maintenance.getName()); + } + } else { + iterator.remove(); + } } } else { iterator.remove(); @@ -109,6 +124,7 @@ public final class Events { jxlsContext.putVar("devices", devicesEvents); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("geofenceNames", geofenceNames); + jxlsContext.putVar("maintenanceNames", maintenanceNames); jxlsContext.putVar("from", from); jxlsContext.putVar("to", to); ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index e04f2f90c..ea383d598 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -151,8 +151,10 @@ public final class ReportUtils { return jxlsContext; } - public static void processTemplateWithSheets(InputStream templateStream, OutputStream targetStream, + public static void processTemplateWithSheets( + InputStream templateStream, OutputStream targetStream, org.jxls.common.Context jxlsContext) throws IOException { + Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); List<Area> xlsAreas = new XlsCommentAreaBuilder(transformer).build(); for (Area xlsArea : xlsAreas) { @@ -166,6 +168,7 @@ public final class ReportUtils { private static TripReport calculateTrip( ArrayList<Position> positions, int startIndex, int endIndex, boolean ignoreOdometer) { + Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -217,10 +220,22 @@ public final class ReportUtils { trip.setDriverUniqueId(findDriver(startTrip, endTrip)); trip.setDriverName(findDriverName(trip.getDriverUniqueId())); + if (!ignoreOdometer + && startTrip.getDouble(Position.KEY_ODOMETER) != 0 + && endTrip.getDouble(Position.KEY_ODOMETER) != 0) { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_ODOMETER)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_ODOMETER)); + } else { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + return trip; } - private static StopReport calculateStop(ArrayList<Position> positions, int startIndex, int endIndex) { + private static StopReport calculateStop( + ArrayList<Position> positions, int startIndex, int endIndex, boolean ignoreOdometer) { + Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -248,24 +263,42 @@ public final class ReportUtils { stop.setSpentFuel(calculateFuel(startStop, endStop)); long engineHours = 0; - for (int i = startIndex + 1; i <= endIndex; i++) { - if (positions.get(i).getBoolean(Position.KEY_IGNITION) - && positions.get(i - 1).getBoolean(Position.KEY_IGNITION)) { - engineHours += positions.get(i).getFixTime().getTime() - positions.get(i - 1).getFixTime().getTime(); + if (startStop.getAttributes().containsKey(Position.KEY_HOURS) + && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { + engineHours = endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS); + } else if (Context.getConfig().getBoolean("processing.engineHours.enable")) { + // Temporary fallback for old data, to be removed in May 2019 + for (int i = startIndex + 1; i <= endIndex; i++) { + if (positions.get(i).getBoolean(Position.KEY_IGNITION) + && positions.get(i - 1).getBoolean(Position.KEY_IGNITION)) { + engineHours += positions.get(i).getFixTime().getTime() + - positions.get(i - 1).getFixTime().getTime(); + } } } stop.setEngineHours(engineHours); + if (!ignoreOdometer + && startStop.getDouble(Position.KEY_ODOMETER) != 0 + && endStop.getDouble(Position.KEY_ODOMETER) != 0) { + stop.setStartOdometer(startStop.getDouble(Position.KEY_ODOMETER)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_ODOMETER)); + } else { + stop.setStartOdometer(startStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + return stop; } - private static <T extends BaseReport> T calculateTripOrStop(ArrayList<Position> positions, int startIndex, - int endIndex, boolean ignoreOdometer, Class<T> reportClass) { + private static <T extends BaseReport> T calculateTripOrStop( + ArrayList<Position> positions, int startIndex, int endIndex, boolean ignoreOdometer, Class<T> reportClass) { + if (reportClass.equals(TripReport.class)) { return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(positions, startIndex, endIndex); + return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); } } @@ -289,12 +322,14 @@ public final class ReportUtils { } } - public static <T extends BaseReport> Collection<T> detectTripsAndStops(Collection<Position> positionCollection, + public static <T extends BaseReport> Collection<T> detectTripsAndStops( + Collection<Position> positionCollection, TripsConfig tripsConfig, boolean ignoreOdometer, Class<T> reportClass) { + Collection<T> result = new ArrayList<>(); ArrayList<Position> positions = new ArrayList<>(positionCollection); - if (positions != null && !positions.isEmpty()) { + if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReport.class); MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); DeviceState deviceState = new DeviceState(); @@ -333,6 +368,8 @@ public final class ReportUtils { ignoreOdometer, reportClass)); } } + return result; } + } diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 366e40421..9810424d8 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -44,12 +44,15 @@ public final class Summary { Position firstPosition = null; Position previousPosition = null; double speedSum = 0; + boolean engineHoursEnabled = Context.getConfig().getBoolean("processing.engineHours.enable"); for (Position position : positions) { if (firstPosition == null) { firstPosition = position; } - if (previousPosition != null && position.getBoolean(Position.KEY_IGNITION) + if (engineHoursEnabled && previousPosition != null + && position.getBoolean(Position.KEY_IGNITION) && previousPosition.getBoolean(Position.KEY_IGNITION)) { + // Temporary fallback for old data, to be removed in May 2019 result.addEngineHours(position.getFixTime().getTime() - previousPosition.getFixTime().getTime()); } @@ -62,6 +65,24 @@ public final class Summary { result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); result.setAverageSpeed(speedSum / positions.size()); result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); + + if (engineHoursEnabled + && firstPosition.getAttributes().containsKey(Position.KEY_HOURS) + && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { + result.setEngineHours( + previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS)); + } + + if (!ignoreOdometer + && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 + && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); + } else { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + } return result; } diff --git a/src/org/traccar/reports/model/BaseReport.java b/src/org/traccar/reports/model/BaseReport.java index 941e2757f..9f2d1188c 100644 --- a/src/org/traccar/reports/model/BaseReport.java +++ b/src/org/traccar/reports/model/BaseReport.java @@ -84,4 +84,23 @@ public class BaseReport { this.spentFuel = spentFuel; } + private double startOdometer; + + public double getStartOdometer() { + return startOdometer; + } + + public void setStartOdometer(double startOdometer) { + this.startOdometer = startOdometer; + } + private double endOdometer; + + public double getEndOdometer() { + return endOdometer; + } + + public void setEndOdometer(double endOdometer) { + this.endOdometer = endOdometer; + } + } diff --git a/src/org/traccar/smpp/SmppClient.java b/src/org/traccar/smpp/SmppClient.java index 97830dd00..d5e6820ab 100644 --- a/src/org/traccar/smpp/SmppClient.java +++ b/src/org/traccar/smpp/SmppClient.java @@ -50,7 +50,7 @@ public class SmppClient implements SMSManager { private SmppSession smppSession; private DefaultSmppSessionHandler sessionHandler = new ClientSmppSessionHandler(this); private ExecutorService executorService = Executors.newCachedThreadPool(); - private DefaultSmppClient clientBootstrap = new DefaultSmppClient(executorService, 1); + private DefaultSmppClient clientBootstrap = new DefaultSmppClient(); private ScheduledExecutorService enquireLinkExecutor; private ScheduledFuture<?> enquireLinkTask; |