diff options
Diffstat (limited to 'src/org/traccar')
680 files changed, 0 insertions, 70494 deletions
diff --git a/src/org/traccar/BaseDataHandler.java b/src/org/traccar/BaseDataHandler.java deleted file mode 100644 index 48794b0d7..000000000 --- a/src/org/traccar/BaseDataHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.ChannelInboundHandlerAdapter; -import org.traccar.model.Position; - -public abstract class BaseDataHandler extends ChannelInboundHandlerAdapter { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof Position) { - Position position = handlePosition((Position) msg); - if (position != null) { - ctx.fireChannelRead(position); - } - } else { - super.channelRead(ctx, msg); - } - } - - protected abstract Position handlePosition(Position position); - -} diff --git a/src/org/traccar/BaseFrameDecoder.java b/src/org/traccar/BaseFrameDecoder.java deleted file mode 100644 index f90f90e4b..000000000 --- a/src/org/traccar/BaseFrameDecoder.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 deleted file mode 100644 index 57a68acac..000000000 --- a/src/org/traccar/BaseHttpProtocolDecoder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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 { - - public BaseHttpProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - 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 deleted file mode 100644 index b3d37f689..000000000 --- a/src/org/traccar/BasePipelineFactory.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInboundHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOutboundHandler; -import io.netty.channel.ChannelPipeline; -import io.netty.handler.timeout.IdleStateHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Keys; -import org.traccar.handler.DefaultDataHandler; -import org.traccar.handler.events.AlertEventHandler; -import org.traccar.handler.events.CommandResultEventHandler; -import org.traccar.handler.events.DriverEventHandler; -import org.traccar.handler.events.FuelDropEventHandler; -import org.traccar.handler.events.GeofenceEventHandler; -import org.traccar.handler.events.IgnitionEventHandler; -import org.traccar.handler.events.MaintenanceEventHandler; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.handler.ComputedAttributesHandler; -import org.traccar.handler.CopyAttributesHandler; -import org.traccar.handler.DistanceHandler; -import org.traccar.handler.EngineHoursHandler; -import org.traccar.handler.FilterHandler; -import org.traccar.handler.GeocoderHandler; -import org.traccar.handler.GeolocationHandler; -import org.traccar.handler.HemisphereHandler; -import org.traccar.handler.MotionHandler; -import org.traccar.handler.NetworkMessageHandler; -import org.traccar.handler.OpenChannelHandler; -import org.traccar.handler.RemoteAddressHandler; -import org.traccar.handler.StandardLoggingHandler; - -import java.util.Map; - -public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { - - private static final Logger LOGGER = LoggerFactory.getLogger(BasePipelineFactory.class); - - private final TrackerServer server; - private boolean eventsEnabled; - private int timeout; - - public BasePipelineFactory(TrackerServer server, String protocol) { - this.server = server; - eventsEnabled = Context.getConfig().getBoolean(Keys.EVENT_ENABLE); - timeout = Context.getConfig().getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); - if (timeout == 0) { - timeout = Context.getConfig().getInteger(Keys.SERVER_TIMEOUT); - } - } - - protected abstract void addProtocolHandlers(PipelineBuilder pipeline); - - @SafeVarargs - private final void addHandlers(ChannelPipeline pipeline, Class<? extends ChannelHandler>... handlerClasses) { - for (Class<? extends ChannelHandler> handlerClass : handlerClasses) { - if (handlerClass != null) { - pipeline.addLast(Main.getInjector().getInstance(handlerClass)); - } - } - } - - public static <T extends ChannelHandler> T getHandler(ChannelPipeline pipeline, Class<T> clazz) { - for (Map.Entry<String, ChannelHandler> handlerEntry : pipeline) { - ChannelHandler handler = handlerEntry.getValue(); - if (handler instanceof WrapperInboundHandler) { - handler = ((WrapperInboundHandler) handler).getWrappedHandler(); - } else if (handler instanceof WrapperOutboundHandler) { - handler = ((WrapperOutboundHandler) handler).getWrappedHandler(); - } - if (clazz.isAssignableFrom(handler.getClass())) { - return (T) handler; - } - } - return null; - } - - @Override - protected void initChannel(Channel channel) { - final ChannelPipeline pipeline = channel.pipeline(); - - if (timeout > 0 && !server.isDatagram()) { - pipeline.addLast(new IdleStateHandler(timeout, 0, 0)); - } - pipeline.addLast(new OpenChannelHandler(server)); - pipeline.addLast(new NetworkMessageHandler()); - pipeline.addLast(new StandardLoggingHandler()); - - addProtocolHandlers(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(handler); - }); - - addHandlers( - pipeline, - GeolocationHandler.class, - HemisphereHandler.class, - DistanceHandler.class, - RemoteAddressHandler.class); - - addDynamicHandlers(pipeline); - - addHandlers( - pipeline, - FilterHandler.class, - GeocoderHandler.class, - MotionHandler.class, - EngineHoursHandler.class, - CopyAttributesHandler.class, - ComputedAttributesHandler.class, - WebDataHandler.class, - DefaultDataHandler.class); - - if (eventsEnabled) { - addHandlers( - pipeline, - CommandResultEventHandler.class, - OverspeedEventHandler.class, - FuelDropEventHandler.class, - MotionEventHandler.class, - GeofenceEventHandler.class, - AlertEventHandler.class, - IgnitionEventHandler.class, - MaintenanceEventHandler.class, - DriverEventHandler.class); - } - - pipeline.addLast(new MainEventHandler()); - } - - private void addDynamicHandlers(ChannelPipeline pipeline) { - String handlers = Context.getConfig().getString(Keys.EXTRA_HANDLERS); - if (handlers != null) { - for (String handler : handlers.split(",")) { - try { - pipeline.addLast((ChannelHandler) Class.forName(handler).getDeclaredConstructor().newInstance()); - } catch (ReflectiveOperationException error) { - LOGGER.warn("Dynamic handler error", error); - } - } - } - } - -} diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java deleted file mode 100644 index c0fd1e27f..000000000 --- a/src/org/traccar/BaseProtocol.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - * 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.Unpooled; -import io.netty.handler.codec.string.StringEncoder; -import org.traccar.database.ActiveDevice; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public abstract class BaseProtocol implements Protocol { - - private final String name; - private final Set<String> supportedDataCommands = new HashSet<>(); - private final Set<String> supportedTextCommands = new HashSet<>(); - private final List<TrackerServer> serverList = new LinkedList<>(); - - private StringProtocolEncoder textCommandEncoder = null; - - public static String nameFromClass(Class<?> clazz) { - String className = clazz.getSimpleName(); - return className.substring(0, className.length() - 8).toLowerCase(); - } - - public BaseProtocol() { - name = nameFromClass(getClass()); - } - - @Override - public String getName() { - return name; - } - - protected void addServer(TrackerServer server) { - serverList.add(server); - } - - @Override - public Collection<TrackerServer> getServerList() { - return serverList; - } - - public void setSupportedDataCommands(String... commands) { - supportedDataCommands.addAll(Arrays.asList(commands)); - } - - public void setSupportedTextCommands(String... commands) { - supportedTextCommands.addAll(Arrays.asList(commands)); - } - - public void setSupportedCommands(String... commands) { - supportedDataCommands.addAll(Arrays.asList(commands)); - supportedTextCommands.addAll(Arrays.asList(commands)); - } - - @Override - public Collection<String> getSupportedDataCommands() { - Set<String> commands = new HashSet<>(supportedDataCommands); - commands.add(Command.TYPE_CUSTOM); - return commands; - } - - @Override - public Collection<String> getSupportedTextCommands() { - Set<String> commands = new HashSet<>(supportedTextCommands); - commands.add(Command.TYPE_CUSTOM); - return commands; - } - - @Override - public void sendDataCommand(ActiveDevice activeDevice, Command command) { - if (supportedDataCommands.contains(command.getType())) { - activeDevice.write(command); - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - String data = command.getString(Command.KEY_DATA); - if (BasePipelineFactory.getHandler(activeDevice.getChannel().pipeline(), StringEncoder.class) != null) { - activeDevice.write(data); - } else { - activeDevice.write(Unpooled.wrappedBuffer(DataConverter.parseHex(data))); - } - } else { - throw new RuntimeException("Command " + command.getType() + " is not supported in protocol " + getName()); - } - } - - public void setTextCommandEncoder(StringProtocolEncoder textCommandEncoder) { - this.textCommandEncoder = textCommandEncoder; - } - - @Override - public void sendTextCommand(String destAddress, Command command) throws Exception { - if (Context.getSmsManager() != null) { - if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmsManager().sendMessageSync(destAddress, command.getString(Command.KEY_DATA), true); - } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { - String encodedCommand = (String) textCommandEncoder.encodeCommand(command); - if (encodedCommand != null) { - Context.getSmsManager().sendMessageSync(destAddress, encodedCommand, true); - } else { - throw new RuntimeException("Failed to encode command"); - } - } else { - throw new RuntimeException( - "Command " + command.getType() + " is not supported in protocol " + getName()); - } - } else { - throw new RuntimeException("SMS is not enabled"); - } - } - -} diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java deleted file mode 100644 index aa5be612e..000000000 --- a/src/org/traccar/BaseProtocolDecoder.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 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.Channel; -import io.netty.channel.socket.DatagramChannel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.database.ConnectionManager; -import org.traccar.database.IdentityManager; -import org.traccar.database.StatisticsManager; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Device; -import org.traccar.model.Position; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.TimeZone; - -public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolDecoder.class); - - private static final String PROTOCOL_UNKNOWN = "unknown"; - - private final Config config = Context.getConfig(); - private final IdentityManager identityManager = Context.getIdentityManager(); - private final ConnectionManager connectionManager = Context.getConnectionManager(); - private final StatisticsManager statisticsManager; - private final Protocol protocol; - - public BaseProtocolDecoder(Protocol protocol) { - this.protocol = protocol; - statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; - } - - public String getProtocolName() { - return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; - } - - public String getServer(Channel channel, char delimiter) { - String server = config.getString(getProtocolName() + ".server"); - if (server == null && channel != null) { - InetSocketAddress address = (InetSocketAddress) channel.localAddress(); - server = address.getAddress().getHostAddress() + ":" + address.getPort(); - } - return server != null ? server.replace(':', delimiter) : null; - } - - protected double convertSpeed(double value, String defaultUnits) { - switch (config.getString(getProtocolName() + ".speed", defaultUnits)) { - case "kmh": - return UnitsConverter.knotsFromKph(value); - case "mps": - return UnitsConverter.knotsFromMps(value); - case "mph": - return UnitsConverter.knotsFromMph(value); - case "kn": - default: - return value; - } - } - - protected TimeZone getTimeZone(long deviceId) { - return getTimeZone(deviceId, "UTC"); - } - - protected TimeZone getTimeZone(long deviceId, String defaultTimeZone) { - TimeZone result = TimeZone.getTimeZone(defaultTimeZone); - String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, true); - if (timeZoneName != null) { - result = TimeZone.getTimeZone(timeZoneName); - } else { - int timeZoneOffset = config.getInteger(getProtocolName() + ".timezone", 0); - if (timeZoneOffset != 0) { - result.setRawOffset(timeZoneOffset * 1000); - LOGGER.warn("Config parameter " + getProtocolName() + ".timezone is deprecated"); - } - } - return result; - } - - private DeviceSession channelDeviceSession; // connection-based protocols - private Map<SocketAddress, DeviceSession> addressDeviceSessions = new HashMap<>(); // connectionless protocols - - private long findDeviceId(SocketAddress remoteAddress, String... uniqueIds) { - if (uniqueIds.length > 0) { - long deviceId = 0; - Device device = null; - try { - for (String uniqueId : uniqueIds) { - if (uniqueId != null) { - device = identityManager.getByUniqueId(uniqueId); - if (device != null) { - deviceId = device.getId(); - break; - } - } - } - } catch (Exception e) { - LOGGER.warn("Find device error", e); - } - if (deviceId == 0 && config.getBoolean("database.registerUnknown")) { - return identityManager.addUnknownDevice(uniqueIds[0]); - } - if (device != null && !device.getDisabled() || config.getBoolean("database.storeDisabled")) { - return deviceId; - } - StringBuilder message = new StringBuilder(); - if (deviceId == 0) { - message.append("Unknown device -"); - } else { - message.append("Disabled device -"); - } - for (String uniqueId : uniqueIds) { - message.append(" ").append(uniqueId); - } - if (remoteAddress != null) { - message.append(" (").append(((InetSocketAddress) remoteAddress).getHostString()).append(")"); - } - LOGGER.warn(message.toString()); - } - return 0; - } - - public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - if (channel != null && BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) != null - || config.getBoolean("decoder.ignoreSessionCache")) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return new DeviceSession(deviceId); - } else { - return null; - } - } - if (channel instanceof DatagramChannel) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - DeviceSession deviceSession = addressDeviceSessions.get(remoteAddress); - if (deviceSession != null && (deviceSession.getDeviceId() == deviceId || uniqueIds.length == 0)) { - return deviceSession; - } else if (deviceId != 0) { - deviceSession = new DeviceSession(deviceId); - addressDeviceSessions.put(remoteAddress, deviceSession); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return deviceSession; - } else { - return null; - } - } else { - if (channelDeviceSession == null) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - channelDeviceSession = new DeviceSession(deviceId); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - } - } - return channelDeviceSession; - } - } - - public void getLastLocation(Position position, Date deviceTime) { - if (position.getDeviceId() != 0) { - position.setOutdated(true); - - Position last = identityManager.getLastPosition(position.getDeviceId()); - if (last != null) { - position.setFixTime(last.getFixTime()); - position.setValid(last.getValid()); - position.setLatitude(last.getLatitude()); - position.setLongitude(last.getLongitude()); - position.setAltitude(last.getAltitude()); - position.setSpeed(last.getSpeed()); - position.setCourse(last.getCourse()); - position.setAccuracy(last.getAccuracy()); - } else { - position.setFixTime(new Date(0)); - } - - if (deviceTime != null) { - position.setDeviceTime(deviceTime); - } else { - position.setDeviceTime(new Date()); - } - } - } - - @Override - protected void onMessageEvent( - Channel channel, SocketAddress remoteAddress, Object originalMessage, Object decodedMessage) { - if (statisticsManager != null) { - statisticsManager.registerMessageReceived(); - } - Position position = null; - if (decodedMessage != null) { - if (decodedMessage instanceof Position) { - position = (Position) decodedMessage; - } else if (decodedMessage instanceof Collection) { - Collection positions = (Collection) decodedMessage; - if (!positions.isEmpty()) { - position = (Position) positions.iterator().next(); - } - } - } - if (position != null) { - connectionManager.updateDevice( - position.getDeviceId(), Device.STATUS_ONLINE, new Date()); - } else { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - connectionManager.updateDevice( - deviceSession.getDeviceId(), Device.STATUS_ONLINE, new Date()); - } - } - } - - @Override - protected Object handleEmptyMessage(Channel channel, SocketAddress remoteAddress, Object msg) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (config.getBoolean("database.saveEmpty") && deviceSession != null) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, null); - return position; - } else { - return null; - } - } - -} diff --git a/src/org/traccar/BaseProtocolEncoder.java b/src/org/traccar/BaseProtocolEncoder.java deleted file mode 100644 index d7625e4b8..000000000 --- a/src/org/traccar/BaseProtocolEncoder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - * 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.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.Command; -import org.traccar.model.Device; - -public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolEncoder.class); - - protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getById(deviceId).getUniqueId(); - } - - protected void initDevicePassword(Command command, String defaultPassword) { - if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - Device device = Context.getIdentityManager().getById(command.getDeviceId()); - String password = device.getString(Command.KEY_DEVICE_PASSWORD); - if (password != null) { - command.set(Command.KEY_DEVICE_PASSWORD, password); - } else { - command.set(Command.KEY_DEVICE_PASSWORD, defaultPassword); - } - } - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - - NetworkMessage networkMessage = (NetworkMessage) msg; - - if (networkMessage.getMessage() instanceof Command) { - - Command command = (Command) networkMessage.getMessage(); - Object encodedCommand = encodeCommand(ctx.channel(), command); - - StringBuilder s = new StringBuilder(); - 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) { - s.append("sent"); - } else { - s.append("not sent"); - } - LOGGER.info(s.toString()); - - ctx.write(new NetworkMessage(encodedCommand, networkMessage.getRemoteAddress()), promise); - - } else { - - super.write(ctx, msg, promise); - - } - } - - protected Object encodeCommand(Channel channel, Command command) { - return encodeCommand(command); - } - - protected Object encodeCommand(Command command) { - return null; - } - -} diff --git a/src/org/traccar/CharacterDelimiterFrameDecoder.java b/src/org/traccar/CharacterDelimiterFrameDecoder.java deleted file mode 100644 index eeb8834dc..000000000 --- a/src/org/traccar/CharacterDelimiterFrameDecoder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - * 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.buffer.Unpooled; -import io.netty.handler.codec.DelimiterBasedFrameDecoder; - -public class CharacterDelimiterFrameDecoder extends DelimiterBasedFrameDecoder { - - private static ByteBuf createDelimiter(char delimiter) { - byte[] buf = {(byte) delimiter}; - return Unpooled.wrappedBuffer(buf); - } - - 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 Unpooled.wrappedBuffer(buf); - } - - 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]); - } - return result; - } - - public CharacterDelimiterFrameDecoder(int maxFrameLength, char delimiter) { - super(maxFrameLength, createDelimiter(delimiter)); - } - - public CharacterDelimiterFrameDecoder(int maxFrameLength, String delimiter) { - super(maxFrameLength, createDelimiter(delimiter)); - } - - public CharacterDelimiterFrameDecoder(int maxFrameLength, boolean stripDelimiter, String delimiter) { - super(maxFrameLength, stripDelimiter, createDelimiter(delimiter)); - } - - public CharacterDelimiterFrameDecoder(int maxFrameLength, String... delimiters) { - super(maxFrameLength, convertDelimiters(delimiters)); - } - - public CharacterDelimiterFrameDecoder(int maxFrameLength, boolean stripDelimiter, String... delimiters) { - super(maxFrameLength, stripDelimiter, convertDelimiters(delimiters)); - } - -} diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java deleted file mode 100644 index 9c20db9e4..000000000 --- a/src/org/traccar/Context.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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 com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr353.JSR353Module; -import org.apache.velocity.app.VelocityEngine; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.database.AttributesManager; -import org.traccar.database.BaseObjectManager; -import org.traccar.database.CalendarManager; -import org.traccar.database.CommandsManager; -import org.traccar.database.ConnectionManager; -import org.traccar.database.DataManager; -import org.traccar.database.DeviceManager; -import org.traccar.database.DriversManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.GroupsManager; -import org.traccar.database.IdentityManager; -import org.traccar.database.LdapProvider; -import org.traccar.database.MailManager; -import org.traccar.database.MaintenancesManager; -import org.traccar.database.MediaManager; -import org.traccar.database.NotificationManager; -import org.traccar.database.PermissionsManager; -import org.traccar.database.UsersManager; -import org.traccar.geocoder.Geocoder; -import org.traccar.helper.Log; -import org.traccar.helper.SanitizerModule; -import org.traccar.model.Attribute; -import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; -import org.traccar.model.Command; -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.notification.EventForwarder; -import org.traccar.notification.JsonTypeEventForwarder; -import org.traccar.notification.NotificatorManager; -import org.traccar.reports.model.TripsConfig; -import org.traccar.sms.SmsManager; -import org.traccar.sms.smpp.SmppClient; -import org.traccar.web.WebServer; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.ext.ContextResolver; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Properties; - -public final class Context { - - private static final Logger LOGGER = LoggerFactory.getLogger(Context.class); - - private Context() { - } - - private static Config config; - - public static Config getConfig() { - return config; - } - - private static ObjectMapper objectMapper; - - public static ObjectMapper getObjectMapper() { - return objectMapper; - } - - private static IdentityManager identityManager; - - public static IdentityManager getIdentityManager() { - return identityManager; - } - - private static DataManager dataManager; - - public static DataManager getDataManager() { - return dataManager; - } - - private static LdapProvider ldapProvider; - - public static LdapProvider getLdapProvider() { - return ldapProvider; - } - - private static MailManager mailManager; - - public static MailManager getMailManager() { - return mailManager; - } - - private static MediaManager mediaManager; - - public static MediaManager getMediaManager() { - return mediaManager; - } - - private static UsersManager usersManager; - - public static UsersManager getUsersManager() { - return usersManager; - } - - private static GroupsManager groupsManager; - - public static GroupsManager getGroupsManager() { - return groupsManager; - } - - private static DeviceManager deviceManager; - - public static DeviceManager getDeviceManager() { - return deviceManager; - } - - private static ConnectionManager connectionManager; - - public static ConnectionManager getConnectionManager() { - return connectionManager; - } - - private static PermissionsManager permissionsManager; - - public static PermissionsManager getPermissionsManager() { - return permissionsManager; - } - - public static Geocoder getGeocoder() { - return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; - } - - private static WebServer webServer; - - public static WebServer getWebServer() { - return webServer; - } - - private static ServerManager serverManager; - - public static ServerManager getServerManager() { - return serverManager; - } - - private static GeofenceManager geofenceManager; - - public static GeofenceManager getGeofenceManager() { - return geofenceManager; - } - - private static CalendarManager calendarManager; - - public static CalendarManager getCalendarManager() { - return calendarManager; - } - - private static NotificationManager notificationManager; - - public static NotificationManager getNotificationManager() { - return notificationManager; - } - - private static NotificatorManager notificatorManager; - - public static NotificatorManager getNotificatorManager() { - return notificatorManager; - } - - private static VelocityEngine velocityEngine; - - public static VelocityEngine getVelocityEngine() { - return velocityEngine; - } - - private static Client client = ClientBuilder.newClient(); - - public static Client getClient() { - return client; - } - - private static EventForwarder eventForwarder; - - public static EventForwarder getEventForwarder() { - return eventForwarder; - } - - private static AttributesManager attributesManager; - - public static AttributesManager getAttributesManager() { - return attributesManager; - } - - private static DriversManager driversManager; - - public static DriversManager getDriversManager() { - return driversManager; - } - - private static CommandsManager commandsManager; - - public static CommandsManager getCommandsManager() { - return commandsManager; - } - - private static MaintenancesManager maintenancesManager; - - public static MaintenancesManager getMaintenancesManager() { - return maintenancesManager; - } - - private static SmsManager smsManager; - - public static SmsManager getSmsManager() { - return smsManager; - } - - private static TripsConfig tripsConfig; - - public static TripsConfig getTripsConfig() { - return tripsConfig; - } - - public static TripsConfig initTripsConfig() { - return new TripsConfig( - config.getLong("report.trip.minimalTripDistance", 500), - config.getLong("report.trip.minimalTripDuration", 300) * 1000, - config.getLong("report.trip.minimalParkingDuration", 300) * 1000, - config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000, - config.getBoolean("report.trip.useIgnition"), - config.getBoolean("event.motion.processInvalidPositions"), - config.getDouble("event.motion.speedThreshold", 0.01)); - } - - private static class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { - - @Override - public ObjectMapper getContext(Class<?> clazz) { - return objectMapper; - } - - } - - public static void init(String configFile) throws Exception { - - try { - config = new Config(configFile); - } catch (Exception e) { - config = new Config(); - Log.setupDefaultLogger(); - throw e; - } - - if (config.getBoolean("logger.enable")) { - Log.setupLogger(config); - } - - objectMapper = new ObjectMapper(); - objectMapper.registerModule(new SanitizerModule()); - 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); - } - - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - - if (config.hasKey("database.url")) { - dataManager = new DataManager(config); - } - - if (config.getBoolean("ldap.enable")) { - ldapProvider = new LdapProvider(config); - } - - mailManager = new MailManager(); - - mediaManager = new MediaManager(config.getString("media.path")); - - if (dataManager != null) { - usersManager = new UsersManager(dataManager); - groupsManager = new GroupsManager(dataManager); - deviceManager = new DeviceManager(dataManager); - } - - identityManager = deviceManager; - - if (config.getBoolean("web.enable")) { - webServer = new WebServer(config); - } - - permissionsManager = new PermissionsManager(dataManager, usersManager); - - connectionManager = new ConnectionManager(); - - tripsConfig = initTripsConfig(); - - if (config.getBoolean("sms.enable")) { - final String smsManagerClass = config.getString("sms.manager.class", SmppClient.class.getCanonicalName()); - try { - smsManager = (SmsManager) Class.forName(smsManagerClass).newInstance(); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - LOGGER.warn("Error loading SMS Manager class : " + smsManagerClass, e); - } - } - - if (config.getBoolean("event.enable")) { - initEventsModule(); - } - - serverManager = new ServerManager(); - - if (config.getBoolean("event.forward.enable")) { - eventForwarder = new JsonTypeEventForwarder(); - } - - attributesManager = new AttributesManager(dataManager); - - driversManager = new DriversManager(dataManager); - - commandsManager = new CommandsManager(dataManager, config.getBoolean("commands.queueing")); - - } - - private static void initEventsModule() { - - geofenceManager = new GeofenceManager(dataManager); - calendarManager = new CalendarManager(dataManager); - maintenancesManager = new MaintenancesManager(dataManager); - notificationManager = new NotificationManager(dataManager); - notificatorManager = new NotificatorManager(); - Properties velocityProperties = new Properties(); - velocityProperties.setProperty("file.resource.loader.path", - Context.getConfig().getString("templates.rootPath", "templates") + "/"); - velocityProperties.setProperty("runtime.log.logsystem.class", - "org.apache.velocity.runtime.log.NullLogChute"); - - String address; - try { - address = config.getString("web.address", InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - - String webUrl = URIUtil.newURI("http", address, config.getInteger("web.port", 8082), "", ""); - webUrl = Context.getConfig().getString("web.url", webUrl); - velocityProperties.setProperty("web.url", webUrl); - - velocityEngine = new VelocityEngine(); - velocityEngine.init(velocityProperties); - } - - public static void init(IdentityManager testIdentityManager, MediaManager testMediaManager) { - config = new Config(); - objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JSR353Module()); - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - identityManager = testIdentityManager; - mediaManager = testMediaManager; - } - - public static <T extends BaseModel> BaseObjectManager<T> getManager(Class<T> clazz) { - if (clazz.equals(Device.class)) { - return (BaseObjectManager<T>) deviceManager; - } else if (clazz.equals(Group.class)) { - return (BaseObjectManager<T>) groupsManager; - } else if (clazz.equals(User.class)) { - return (BaseObjectManager<T>) usersManager; - } else if (clazz.equals(Calendar.class)) { - return (BaseObjectManager<T>) calendarManager; - } else if (clazz.equals(Attribute.class)) { - return (BaseObjectManager<T>) attributesManager; - } else if (clazz.equals(Geofence.class)) { - return (BaseObjectManager<T>) geofenceManager; - } else if (clazz.equals(Driver.class)) { - 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; - } - return null; - } - -} diff --git a/src/org/traccar/DeviceSession.java b/src/org/traccar/DeviceSession.java deleted file mode 100644 index 322381807..000000000 --- a/src/org/traccar/DeviceSession.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 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.util.TimeZone; - -public class DeviceSession { - - private final long deviceId; - - public DeviceSession(long deviceId) { - this.deviceId = deviceId; - } - - public long getDeviceId() { - return deviceId; - } - - private TimeZone timeZone; - - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - public TimeZone getTimeZone() { - return timeZone; - } - -} diff --git a/src/org/traccar/EventLoopGroupFactory.java b/src/org/traccar/EventLoopGroupFactory.java deleted file mode 100644 index 482559253..000000000 --- a/src/org/traccar/EventLoopGroupFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 deleted file mode 100644 index 681924e87..000000000 --- a/src/org/traccar/ExtendedObjectDecoder.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - * 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.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; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Collection; - -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 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))); - } - } - } - - @Override - 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(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage); - } - if (decodedMessage != null) { - if (decodedMessage instanceof Collection) { - for (Object o : (Collection) decodedMessage) { - saveOriginal(o, originalMessage); - ctx.fireChannelRead(o); - } - } else { - saveOriginal(decodedMessage, originalMessage); - ctx.fireChannelRead(decodedMessage); - } - } - } finally { - ReferenceCountUtil.release(originalMessage); - } - } - - protected void onMessageEvent( - Channel channel, SocketAddress remoteAddress, Object originalMessage, Object decodedMessage) { - } - - protected Object handleEmptyMessage(Channel channel, SocketAddress remoteAddress, Object msg) { - return null; - } - - protected abstract Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception; - -} diff --git a/src/org/traccar/GlobalTimer.java b/src/org/traccar/GlobalTimer.java deleted file mode 100644 index a97321ba2..000000000 --- a/src/org/traccar/GlobalTimer.java +++ /dev/null @@ -1,42 +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 io.netty.util.HashedWheelTimer; -import io.netty.util.Timer; - -public final class GlobalTimer { - - private static Timer instance = null; - - private GlobalTimer() { - } - - public static void release() { - if (instance != null) { - instance.stop(); - } - instance = null; - } - - public static Timer getTimer() { - if (instance == null) { - instance = new HashedWheelTimer(); - } - return instance; - } - -} diff --git a/src/org/traccar/Main.java b/src/org/traccar/Main.java deleted file mode 100644 index 6ebd1d399..000000000 --- a/src/org/traccar/Main.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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 com.google.inject.Guice; -import com.google.inject.Injector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryMXBean; -import java.lang.management.OperatingSystemMXBean; -import java.lang.management.RuntimeMXBean; -import java.nio.charset.Charset; -import java.sql.SQLException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.Locale; - -public final class Main { - - private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); - - private static final long CLEAN_PERIOD = 24 * 60 * 60 * 1000; - - private static Injector injector; - - public static Injector getInjector() { - return injector; - } - - private Main() { - } - - public static void logSystemInfo() { - try { - OperatingSystemMXBean operatingSystemBean = ManagementFactory.getOperatingSystemMXBean(); - LOGGER.info("Operating system" - + " name: " + operatingSystemBean.getName() - + " version: " + operatingSystemBean.getVersion() - + " architecture: " + operatingSystemBean.getArch()); - - RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); - LOGGER.info("Java runtime" - + " name: " + runtimeBean.getVmName() - + " vendor: " + runtimeBean.getVmVendor() - + " version: " + runtimeBean.getVmVersion()); - - MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); - LOGGER.info("Memory limit" - + " heap: " + memoryBean.getHeapMemoryUsage().getMax() / (1024 * 1024) + "mb" - + " non-heap: " + memoryBean.getNonHeapMemoryUsage().getMax() / (1024 * 1024) + "mb"); - - LOGGER.info("Character encoding: " - + System.getProperty("file.encoding") + " charset: " + Charset.defaultCharset()); - - } catch (Exception error) { - LOGGER.warn("Failed to get system info"); - } - } - - public static void main(String[] args) throws Exception { - Locale.setDefault(Locale.ENGLISH); - - if (args.length <= 0) { - throw new RuntimeException("Configuration file is not provided"); - } - - final String configFile = args[args.length - 1]; - - if (args[0].startsWith("--")) { - WindowsService windowsService = new WindowsService("traccar") { - @Override - public void run() { - Main.run(configFile); - } - }; - switch (args[0]) { - case "--install": - windowsService.install("traccar", null, null, null, null, configFile); - return; - case "--uninstall": - windowsService.uninstall(); - return; - case "--service": - default: - windowsService.init(); - break; - } - } else { - run(configFile); - } - } - - public static void run(String configFile) { - try { - Context.init(configFile); - injector = Guice.createInjector(new MainModule()); - logSystemInfo(); - LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); - LOGGER.info("Starting server..."); - - Context.getServerManager().start(); - if (Context.getWebServer() != null) { - Context.getWebServer().start(); - } - - new Timer().scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - Context.getDataManager().clearHistory(); - } catch (SQLException error) { - LOGGER.warn("Clear history error", error); - } - } - }, 0, CLEAN_PERIOD); - - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - LOGGER.error("Thread exception", e); - } - }); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - LOGGER.info("Shutting down server..."); - - if (Context.getWebServer() != null) { - Context.getWebServer().stop(); - } - Context.getServerManager().stop(); - } - }); - } catch (Exception e) { - LOGGER.error("Main method error", e); - throw new RuntimeException(e); - } - } - -} diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java deleted file mode 100644 index a8b53ff60..000000000 --- a/src/org/traccar/MainEventHandler.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.socket.DatagramChannel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.timeout.IdleStateEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.database.StatisticsManager; -import org.traccar.helper.DateUtil; -import org.traccar.model.Position; - -import java.sql.SQLException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -public class MainEventHandler extends ChannelInboundHandlerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(MainEventHandler.class); - - private static final String DEFAULT_LOGGER_ATTRIBUTES = "time,position,speed,course,accuracy,result"; - - private final Set<String> connectionlessProtocols = new HashSet<>(); - private final Set<String> logAttributes = new LinkedHashSet<>(); - - public MainEventHandler() { - String connectionlessProtocolList = Context.getConfig().getString("status.ignoreOffline"); - if (connectionlessProtocolList != null) { - connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split(","))); - } - logAttributes.addAll(Arrays.asList( - Context.getConfig().getString("logger.attributes", DEFAULT_LOGGER_ATTRIBUTES).split(","))); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) { - if (msg instanceof Position) { - - Position position = (Position) msg; - try { - Context.getDeviceManager().updateLatestPosition(position); - } catch (SQLException error) { - LOGGER.warn("Failed to update device", error); - } - - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); - - StringBuilder builder = new StringBuilder(); - builder.append(formatChannel(ctx.channel())).append(" "); - builder.append("id: ").append(uniqueId); - for (String attribute : logAttributes) { - switch (attribute) { - case "time": - builder.append(", time: ").append(DateUtil.formatDate(position.getFixTime(), false)); - break; - case "position": - builder.append(", lat: ").append(String.format("%.5f", position.getLatitude())); - builder.append(", lon: ").append(String.format("%.5f", position.getLongitude())); - break; - case "speed": - if (position.getSpeed() > 0) { - builder.append(", speed: ").append(String.format("%.1f", position.getSpeed())); - } - break; - case "course": - builder.append(", course: ").append(String.format("%.1f", position.getCourse())); - break; - case "accuracy": - if (position.getAccuracy() > 0) { - builder.append(", accuracy: ").append(String.format("%.1f", position.getAccuracy())); - } - break; - case "outdated": - if (position.getOutdated()) { - builder.append(", outdated"); - } - break; - case "invalid": - if (!position.getValid()) { - builder.append(", invalid"); - } - break; - default: - Object value = position.getAttributes().get(attribute); - if (value != null) { - builder.append(", ").append(attribute).append(": ").append(value); - } - break; - } - } - LOGGER.info(builder.toString()); - - Main.getInjector().getInstance(StatisticsManager.class).registerMessageStored(position.getDeviceId()); - } - } - - private static String formatChannel(Channel channel) { - return String.format("[%s]", channel.id().asShortText()); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) { - if (!(ctx.channel() instanceof DatagramChannel)) { - LOGGER.info(formatChannel(ctx.channel()) + " connected"); - } - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) { - LOGGER.info(formatChannel(ctx.channel()) + " disconnected"); - closeChannel(ctx.channel()); - - if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null - && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().removeActiveDevice(ctx.channel()); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - while (cause.getCause() != null && cause.getCause() != cause) { - cause = cause.getCause(); - } - LOGGER.warn(formatChannel(ctx.channel()) + " error", cause); - closeChannel(ctx.channel()); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { - if (evt instanceof IdleStateEvent) { - LOGGER.info(formatChannel(ctx.channel()) + " timed out"); - closeChannel(ctx.channel()); - } - } - - private void closeChannel(Channel channel) { - if (!(channel instanceof DatagramChannel)) { - channel.close(); - } - } - -} diff --git a/src/org/traccar/MainModule.java b/src/org/traccar/MainModule.java deleted file mode 100644 index 6fe8bad1c..000000000 --- a/src/org/traccar/MainModule.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright 2018 - 2019 Anton Tananaev (anton@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 com.fasterxml.jackson.databind.ObjectMapper; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; -import org.traccar.database.CalendarManager; -import org.traccar.database.DataManager; -import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; -import org.traccar.database.StatisticsManager; -import org.traccar.geocoder.AddressFormat; -import org.traccar.geocoder.BanGeocoder; -import org.traccar.geocoder.BingMapsGeocoder; -import org.traccar.geocoder.FactualGeocoder; -import org.traccar.geocoder.GeocodeFarmGeocoder; -import org.traccar.geocoder.GeocodeXyzGeocoder; -import org.traccar.geocoder.Geocoder; -import org.traccar.geocoder.GisgraphyGeocoder; -import org.traccar.geocoder.GoogleGeocoder; -import org.traccar.geocoder.HereGeocoder; -import org.traccar.geocoder.MapQuestGeocoder; -import org.traccar.geocoder.MapmyIndiaGeocoder; -import org.traccar.geocoder.NominatimGeocoder; -import org.traccar.geocoder.OpenCageGeocoder; -import org.traccar.geolocation.GeolocationProvider; -import org.traccar.geolocation.GoogleGeolocationProvider; -import org.traccar.geolocation.MozillaGeolocationProvider; -import org.traccar.geolocation.OpenCellIdGeolocationProvider; -import org.traccar.geolocation.UnwiredGeolocationProvider; -import org.traccar.handler.ComputedAttributesHandler; -import org.traccar.handler.CopyAttributesHandler; -import org.traccar.handler.DefaultDataHandler; -import org.traccar.handler.DistanceHandler; -import org.traccar.handler.EngineHoursHandler; -import org.traccar.handler.FilterHandler; -import org.traccar.handler.GeocoderHandler; -import org.traccar.handler.GeolocationHandler; -import org.traccar.handler.HemisphereHandler; -import org.traccar.handler.MotionHandler; -import org.traccar.handler.RemoteAddressHandler; -import org.traccar.handler.events.AlertEventHandler; -import org.traccar.handler.events.CommandResultEventHandler; -import org.traccar.handler.events.DriverEventHandler; -import org.traccar.handler.events.FuelDropEventHandler; -import org.traccar.handler.events.GeofenceEventHandler; -import org.traccar.handler.events.IgnitionEventHandler; -import org.traccar.handler.events.MaintenanceEventHandler; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.reports.model.TripsConfig; - -import javax.annotation.Nullable; -import javax.ws.rs.client.Client; - -public class MainModule extends AbstractModule { - - @Provides - public static ObjectMapper provideObjectMapper() { - return Context.getObjectMapper(); - } - - @Provides - public static Config provideConfig() { - return Context.getConfig(); - } - - @Provides - public static DataManager provideDataManager() { - return Context.getDataManager(); - } - - @Provides - public static IdentityManager provideIdentityManager() { - return Context.getIdentityManager(); - } - - @Provides - public static Client provideClient() { - return Context.getClient(); - } - - @Provides - public static TripsConfig provideTripsConfig() { - return Context.getTripsConfig(); - } - - @Provides - public static DeviceManager provideDeviceManager() { - return Context.getDeviceManager(); - } - - @Provides - public static GeofenceManager provideGeofenceManager() { - return Context.getGeofenceManager(); - } - - @Provides - public static CalendarManager provideCalendarManager() { - return Context.getCalendarManager(); - } - - @Provides - public static AttributesManager provideAttributesManager() { - return Context.getAttributesManager(); - } - - @Provides - public static MaintenancesManager provideMaintenancesManager() { - return Context.getMaintenancesManager(); - } - - @Singleton - @Provides - public static StatisticsManager provideStatisticsManager(Config config, DataManager dataManager, Client client) { - return new StatisticsManager(config, dataManager, client); - } - - @Singleton - @Provides - public static Geocoder provideGeocoder(Config config) { - if (config.getBoolean(Keys.GEOCODER_ENABLE)) { - String type = config.getString(Keys.GEOCODER_TYPE, "google"); - String url = config.getString(Keys.GEOCODER_URL); - String id = config.getString(Keys.GEOCODER_ID); - String key = config.getString(Keys.GEOCODER_KEY); - String language = config.getString(Keys.GEOCODER_LANGUAGE); - String formatString = config.getString(Keys.GEOCODER_FORMAT); - AddressFormat addressFormat = formatString != null ? new AddressFormat(formatString) : new AddressFormat(); - - int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); - switch (type) { - case "nominatim": - return new NominatimGeocoder(url, key, language, cacheSize, addressFormat); - case "gisgraphy": - return new GisgraphyGeocoder(url, cacheSize, addressFormat); - case "mapquest": - return new MapQuestGeocoder(url, key, cacheSize, addressFormat); - case "opencage": - return new OpenCageGeocoder(url, key, cacheSize, addressFormat); - case "bingmaps": - return new BingMapsGeocoder(url, key, cacheSize, addressFormat); - case "factual": - return new FactualGeocoder(url, key, cacheSize, addressFormat); - case "geocodefarm": - return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); - case "geocodexyz": - return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); - case "ban": - return new BanGeocoder(cacheSize, addressFormat); - case "here": - return new HereGeocoder(id, key, language, cacheSize, addressFormat); - case "mapmyindia": - return new MapmyIndiaGeocoder(url, key, cacheSize, addressFormat); - default: - return new GoogleGeocoder(key, language, cacheSize, addressFormat); - } - } - return null; - } - - @Singleton - @Provides - public static GeolocationProvider provideGeolocationProvider(Config config) { - if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { - String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); - String url = config.getString(Keys.GEOLOCATION_URL); - String key = config.getString(Keys.GEOLOCATION_KEY); - switch (type) { - case "google": - return new GoogleGeolocationProvider(key); - case "opencellid": - return new OpenCellIdGeolocationProvider(key); - case "unwired": - return new UnwiredGeolocationProvider(url, key); - default: - return new MozillaGeolocationProvider(key); - } - } - return null; - } - - @Singleton - @Provides - public static DistanceHandler provideDistanceHandler(Config config, IdentityManager identityManager) { - return new DistanceHandler(config, identityManager); - } - - @Singleton - @Provides - public static FilterHandler provideFilterHandler(Config config) { - if (config.getBoolean(Keys.FILTER_ENABLE)) { - return new FilterHandler(config); - } - return null; - } - - @Singleton - @Provides - public static HemisphereHandler provideHemisphereHandler(Config config) { - if (config.hasKey(Keys.LOCATION_LATITUDE_HEMISPHERE) || config.hasKey(Keys.LOCATION_LONGITUDE_HEMISPHERE)) { - return new HemisphereHandler(config); - } - return null; - } - - @Singleton - @Provides - public static RemoteAddressHandler provideRemoteAddressHandler(Config config) { - if (config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE)) { - return new RemoteAddressHandler(); - } - return null; - } - - @Singleton - @Provides - public static WebDataHandler provideWebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { - if (config.getBoolean(Keys.FORWARD_ENABLE)) { - return new WebDataHandler(config, identityManager, objectMapper, client); - } - return null; - } - - @Singleton - @Provides - public static GeolocationHandler provideGeolocationHandler( - Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { - if (geolocationProvider != null) { - return new GeolocationHandler(config, geolocationProvider, statisticsManager); - } - return null; - } - - @Singleton - @Provides - public static GeocoderHandler provideGeocoderHandler( - Config config, @Nullable Geocoder geocoder, IdentityManager identityManager, - StatisticsManager statisticsManager) { - if (geocoder != null) { - return new GeocoderHandler(config, geocoder, identityManager, statisticsManager); - } - return null; - } - - @Singleton - @Provides - public static MotionHandler provideMotionHandler(TripsConfig tripsConfig) { - return new MotionHandler(tripsConfig.getSpeedThreshold()); - } - - @Singleton - @Provides - public static EngineHoursHandler provideEngineHoursHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_ENGINE_HOURS_ENABLE)) { - return new EngineHoursHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static CopyAttributesHandler provideCopyAttributesHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE)) { - return new CopyAttributesHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static ComputedAttributesHandler provideComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { - if (config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ENABLE)) { - return new ComputedAttributesHandler(config, identityManager, attributesManager); - } - return null; - } - - @Singleton - @Provides - public static DefaultDataHandler provideDefaultDataHandler(@Nullable DataManager dataManager) { - if (dataManager != null) { - return new DefaultDataHandler(dataManager); - } - return null; - } - - @Singleton - @Provides - public static CommandResultEventHandler provideCommandResultEventHandler() { - return new CommandResultEventHandler(); - } - - @Singleton - @Provides - public static OverspeedEventHandler provideOverspeedEventHandler( - Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { - return new OverspeedEventHandler(config, deviceManager, geofenceManager); - } - - @Singleton - @Provides - public static FuelDropEventHandler provideFuelDropEventHandler(IdentityManager identityManager) { - return new FuelDropEventHandler(identityManager); - } - - @Singleton - @Provides - public static MotionEventHandler provideMotionEventHandler( - IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - return new MotionEventHandler(identityManager, deviceManager, tripsConfig); - } - - @Singleton - @Provides - public static GeofenceEventHandler provideGeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { - return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager); - } - - @Singleton - @Provides - public static AlertEventHandler provideAlertEventHandler(Config config, IdentityManager identityManager) { - return new AlertEventHandler(config, identityManager); - } - - @Singleton - @Provides - public static IgnitionEventHandler provideIgnitionEventHandler(IdentityManager identityManager) { - return new IgnitionEventHandler(identityManager); - } - - @Singleton - @Provides - public static MaintenanceEventHandler provideMaintenanceEventHandler( - IdentityManager identityManager, MaintenancesManager maintenancesManager) { - return new MaintenanceEventHandler(identityManager, maintenancesManager); - } - - @Singleton - @Provides - public static DriverEventHandler provideDriverEventHandler(IdentityManager identityManager) { - return new DriverEventHandler(identityManager); - } - - @Override - protected void configure() { - binder().requireExplicitBindings(); - } - -} diff --git a/src/org/traccar/NetworkMessage.java b/src/org/traccar/NetworkMessage.java deleted file mode 100644 index 14a397e69..000000000 --- a/src/org/traccar/NetworkMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 deleted file mode 100644 index 3334040b1..000000000 --- a/src/org/traccar/PipelineBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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(ChannelHandler handler); - -} diff --git a/src/org/traccar/Protocol.java b/src/org/traccar/Protocol.java deleted file mode 100644 index 3b66f2598..000000000 --- a/src/org/traccar/Protocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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; -import org.traccar.model.Command; - -import java.util.Collection; - -public interface Protocol { - - String getName(); - - Collection<TrackerServer> getServerList(); - - Collection<String> getSupportedDataCommands(); - - void sendDataCommand(ActiveDevice activeDevice, Command command); - - Collection<String> getSupportedTextCommands(); - - void sendTextCommand(String destAddress, Command command) throws Exception; - -} diff --git a/src/org/traccar/ServerManager.java b/src/org/traccar/ServerManager.java deleted file mode 100644 index 6a3273402..000000000 --- a/src/org/traccar/ServerManager.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.net.BindException; -import java.net.URI; -import java.net.URL; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Enumeration; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class ServerManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); - - private final List<TrackerServer> serverList = new LinkedList<>(); - private final Map<String, BaseProtocol> protocolList = new ConcurrentHashMap<>(); - - public ServerManager() throws Exception { - - List<String> names = new LinkedList<>(); - String packageName = "org.traccar.protocol"; - String packagePath = packageName.replace('.', '/'); - URL packageUrl = getClass().getClassLoader().getResource(packagePath); - - if (packageUrl.getProtocol().equals("jar")) { - String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); - try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { - Enumeration<JarEntry> jarEntries = jf.entries(); - while (jarEntries.hasMoreElements()) { - String entryName = jarEntries.nextElement().getName(); - if (entryName.startsWith(packagePath) && entryName.length() > packagePath.length() + 5) { - names.add(entryName.substring(packagePath.length() + 1, entryName.lastIndexOf('.'))); - } - } - } - } else { - File folder = new File(new URI(packageUrl.toString())); - File[] files = folder.listFiles(); - if (files != null) { - for (File actual: files) { - String entryName = actual.getName(); - names.add(entryName.substring(0, entryName.lastIndexOf('.'))); - } - } - } - - for (String name : names) { - Class protocolClass = Class.forName(packageName + '.' + name); - if (BaseProtocol.class.isAssignableFrom(protocolClass) - && Context.getConfig().hasKey(BaseProtocol.nameFromClass(protocolClass) + ".port")) { - BaseProtocol protocol = (BaseProtocol) protocolClass.newInstance(); - serverList.addAll(protocol.getServerList()); - protocolList.put(protocol.getName(), protocol); - } - } - } - - public BaseProtocol getProtocol(String name) { - return protocolList.get(name); - } - - public void start() throws Exception { - for (TrackerServer server: serverList) { - try { - server.start(); - } catch (BindException e) { - LOGGER.warn("Port {} is disabled due to conflict", server.getPort()); - } - } - } - - public void stop() { - for (TrackerServer server: serverList) { - server.stop(); - } - GlobalTimer.release(); - } - -} diff --git a/src/org/traccar/StringProtocolEncoder.java b/src/org/traccar/StringProtocolEncoder.java deleted file mode 100644 index 1945ae174..000000000 --- a/src/org/traccar/StringProtocolEncoder.java +++ /dev/null @@ -1,51 +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; - -import org.traccar.model.Command; - -import java.util.Map; - -public abstract class StringProtocolEncoder extends BaseProtocolEncoder { - - public interface ValueFormatter { - String formatValue(String key, Object value); - } - - protected String formatCommand(Command command, String format, ValueFormatter valueFormatter, String... keys) { - - String result = String.format(format, (Object[]) keys); - - result = result.replaceAll("\\{" + Command.KEY_UNIQUE_ID + "}", getUniqueId(command.getDeviceId())); - for (Map.Entry<String, Object> entry : command.getAttributes().entrySet()) { - String value = null; - if (valueFormatter != null) { - value = valueFormatter.formatValue(entry.getKey(), entry.getValue()); - } - if (value == null) { - value = entry.getValue().toString(); - } - result = result.replaceAll("\\{" + entry.getKey() + "}", value); - } - - return result; - } - - protected String formatCommand(Command command, String format, String... keys) { - return formatCommand(command, format, null, keys); - } - -} diff --git a/src/org/traccar/TrackerServer.java b/src/org/traccar/TrackerServer.java deleted file mode 100644 index 3a1e1c4e8..000000000 --- a/src/org/traccar/TrackerServer.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.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; - -public abstract class TrackerServer { - - private final boolean datagram; - private final AbstractBootstrap bootstrap; - - public boolean isDatagram() { - return datagram; - } - - public TrackerServer(boolean datagram, String protocol) { - this.datagram = datagram; - - address = Context.getConfig().getString(protocol + ".address"); - port = Context.getConfig().getInteger(protocol + ".port"); - - BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { - @Override - 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 addProtocolHandlers(PipelineBuilder pipeline); - - private int port; - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - private String address; - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); - - public ChannelGroup getChannelGroup() { - return channelGroup; - } - - public void start() throws Exception { - InetSocketAddress endpoint; - if (address == null) { - endpoint = new InetSocketAddress(port); - } else { - endpoint = new InetSocketAddress(address, port); - } - - Channel channel = bootstrap.bind(endpoint).sync().channel(); - if (channel != null) { - getChannelGroup().add(channel); - } - } - - public void stop() { - channelGroup.close().awaitUninterruptibly(); - } - -} diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java deleted file mode 100644 index 64396de03..000000000 --- a/src/org/traccar/WebDataHandler.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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 com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.netty.channel.ChannelHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; -import org.traccar.helper.Checksum; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.model.Group; - -import javax.inject.Inject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import java.util.HashMap; -import java.util.Map; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.Formatter; -import java.util.Locale; -import java.util.TimeZone; - -@ChannelHandler.Sharable -public class WebDataHandler extends BaseDataHandler { - - private static final String KEY_POSITION = "position"; - private static final String KEY_DEVICE = "device"; - - private final IdentityManager identityManager; - private final ObjectMapper objectMapper; - private final Client client; - - private final String url; - private final String header; - private final boolean json; - - @Inject - public WebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { - this.identityManager = identityManager; - this.objectMapper = objectMapper; - this.client = client; - this.url = config.getString(Keys.FORWARD_URL); - this.header = config.getString(Keys.FORWARD_HEADER); - this.json = config.getBoolean(Keys.FORWARD_JSON); - } - - private static String formatSentence(Position position) { - - StringBuilder s = new StringBuilder("$GPRMC,"); - - try (Formatter f = new Formatter(s, Locale.ENGLISH)) { - - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); - calendar.setTimeInMillis(position.getFixTime().getTime()); - - f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar); - - double lat = position.getLatitude(); - double lon = position.getLongitude(); - - f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N'); - f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E'); - - f.format("%.2f,%.2f,", position.getSpeed(), position.getCourse()); - f.format("%1$td%1$tm%1$ty,,", calendar); - } - - s.append(Checksum.nmea(s.toString())); - - return s.toString(); - } - - private String calculateStatus(Position position) { - if (position.getAttributes().containsKey(Position.KEY_ALARM)) { - return "0xF841"; // STATUS_PANIC_ON - } else if (position.getSpeed() < 1.0) { - return "0xF020"; // STATUS_LOCATION - } else { - return "0xF11C"; // STATUS_MOTION_MOVING - } - } - - public String formatRequest(Position position) throws UnsupportedEncodingException, JsonProcessingException { - - Device device = identityManager.getById(position.getDeviceId()); - - String request = url - .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8.name())) - .replace("{uniqueId}", device.getUniqueId()) - .replace("{status}", device.getStatus()) - .replace("{deviceId}", String.valueOf(position.getDeviceId())) - .replace("{protocol}", String.valueOf(position.getProtocol())) - .replace("{deviceTime}", String.valueOf(position.getDeviceTime().getTime())) - .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) - .replace("{valid}", String.valueOf(position.getValid())) - .replace("{latitude}", String.valueOf(position.getLatitude())) - .replace("{longitude}", String.valueOf(position.getLongitude())) - .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) { - request = request.replace( - "{address}", URLEncoder.encode(position.getAddress(), StandardCharsets.UTF_8.name())); - } - - if (request.contains("{attributes}")) { - String attributes = objectMapper.writeValueAsString(position.getAttributes()); - request = request.replace( - "{attributes}", URLEncoder.encode(attributes, StandardCharsets.UTF_8.name())); - } - - if (request.contains("{gprmc}")) { - request = request.replace("{gprmc}", formatSentence(position)); - } - - if (request.contains("{group}")) { - String deviceGroupName = ""; - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceGroupName = group.getName(); - } - } - - request = request.replace("{group}", URLEncoder.encode(deviceGroupName, StandardCharsets.UTF_8.name())); - } - - return request; - } - - @Override - protected Position handlePosition(Position position) { - - String url; - if (json) { - url = this.url; - } else { - try { - url = formatRequest(position); - } catch (UnsupportedEncodingException | JsonProcessingException e) { - throw new RuntimeException("Forwarding formatting error", e); - } - } - - Invocation.Builder requestBuilder = client.target(url).request(); - - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - requestBuilder.header(values[0].trim(), values[1].trim()); - } - } - - if (json) { - requestBuilder.async().post(Entity.json(prepareJsonPayload(position))); - } else { - requestBuilder.async().get(); - } - - return position; - } - - private Map<String, Object> prepareJsonPayload(Position position) { - - Map<String, Object> data = new HashMap<>(); - Device device = identityManager.getById(position.getDeviceId()); - - data.put(KEY_POSITION, position); - - if (device != null) { - data.put(KEY_DEVICE, device); - } - - return data; - } - -} diff --git a/src/org/traccar/WindowsService.java b/src/org/traccar/WindowsService.java deleted file mode 100644 index 4a8955608..000000000 --- a/src/org/traccar/WindowsService.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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 com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Advapi32; -import com.sun.jna.platform.win32.WinError; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.Winsvc; -import com.sun.jna.platform.win32.Winsvc.HandlerEx; -import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; -import com.sun.jna.platform.win32.Winsvc.SERVICE_DESCRIPTION; -import com.sun.jna.platform.win32.Winsvc.SERVICE_MAIN_FUNCTION; -import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS; -import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_HANDLE; -import com.sun.jna.platform.win32.Winsvc.SERVICE_TABLE_ENTRY; -import jnr.posix.POSIXFactory; - -import java.io.File; -import java.net.URISyntaxException; - -public abstract class WindowsService { - - private static final Advapi32 ADVAPI_32 = Advapi32.INSTANCE; - - private final Object waitObject = new Object(); - - private String serviceName; - private ServiceMain serviceMain; - private ServiceControl serviceControl; - private SERVICE_STATUS_HANDLE serviceStatusHandle; - - public WindowsService(String serviceName) { - this.serviceName = serviceName; - } - - public boolean install( - String displayName, String description, String[] dependencies, - String account, String password, String config) throws URISyntaxException { - - String javaHome = System.getProperty("java.home"); - String javaBinary = javaHome + "\\bin\\java.exe"; - - File jar = new File(WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - String command = javaBinary - + " -Duser.dir=\"" + jar.getParentFile().getAbsolutePath() + "\"" - + " -jar \"" + jar.getAbsolutePath() + "\"" - + " --service \"" + config + "\""; - - boolean success = false; - StringBuilder dep = new StringBuilder(); - - if (dependencies != null) { - for (String s : dependencies) { - dep.append(s); - dep.append("\0"); - } - } - dep.append("\0"); - - SERVICE_DESCRIPTION desc = new SERVICE_DESCRIPTION(); - desc.lpDescription = description; - - SC_HANDLE serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.CreateService(serviceManager, serviceName, displayName, - Winsvc.SERVICE_ALL_ACCESS, WinNT.SERVICE_WIN32_OWN_PROCESS, WinNT.SERVICE_AUTO_START, - WinNT.SERVICE_ERROR_NORMAL, - command, - null, null, dep.toString(), account, password); - - if (service != null) { - success = ADVAPI_32.ChangeServiceConfig2(service, Winsvc.SERVICE_CONFIG_DESCRIPTION, desc); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - return success; - } - - public boolean uninstall() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.OpenService(serviceManager, serviceName, Winsvc.SERVICE_ALL_ACCESS); - - if (service != null) { - success = ADVAPI_32.DeleteService(service); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - return success; - } - - public boolean start() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); - - if (service != null) { - success = ADVAPI_32.StartService(service, 0, null); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - - return success; - } - - public boolean stop() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); - - if (serviceManager != null) { - SC_HANDLE service = Advapi32.INSTANCE.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); - - if (service != null) { - SERVICE_STATUS serviceStatus = new SERVICE_STATUS(); - success = Advapi32.INSTANCE.ControlService(service, Winsvc.SERVICE_CONTROL_STOP, serviceStatus); - Advapi32.INSTANCE.CloseServiceHandle(service); - } - Advapi32.INSTANCE.CloseServiceHandle(serviceManager); - } - - return success; - } - - public void init() throws URISyntaxException { - String path = new File( - WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent(); - - POSIXFactory.getPOSIX().chdir(path); - - serviceMain = new ServiceMain(); - SERVICE_TABLE_ENTRY entry = new SERVICE_TABLE_ENTRY(); - entry.lpServiceName = serviceName; - entry.lpServiceProc = serviceMain; - - Advapi32.INSTANCE.StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY[]) entry.toArray(2)); - } - - private SC_HANDLE openServiceControlManager(String machine, int access) { - return ADVAPI_32.OpenSCManager(machine, null, access); - } - - private void reportStatus(int status, int win32ExitCode, int waitHint) { - SERVICE_STATUS serviceStatus = new SERVICE_STATUS(); - serviceStatus.dwServiceType = WinNT.SERVICE_WIN32_OWN_PROCESS; - serviceStatus.dwControlsAccepted = Winsvc.SERVICE_ACCEPT_STOP | Winsvc.SERVICE_ACCEPT_SHUTDOWN; - serviceStatus.dwWin32ExitCode = win32ExitCode; - serviceStatus.dwWaitHint = waitHint; - serviceStatus.dwCurrentState = status; - - ADVAPI_32.SetServiceStatus(serviceStatusHandle, serviceStatus); - } - - public abstract void run(); - - private class ServiceMain implements SERVICE_MAIN_FUNCTION { - - public void callback(int dwArgc, Pointer lpszArgv) { - serviceControl = new ServiceControl(); - serviceStatusHandle = ADVAPI_32.RegisterServiceCtrlHandlerEx(serviceName, serviceControl, null); - - reportStatus(Winsvc.SERVICE_START_PENDING, WinError.NO_ERROR, 3000); - reportStatus(Winsvc.SERVICE_RUNNING, WinError.NO_ERROR, 0); - - Thread.currentThread().setContextClassLoader(WindowsService.class.getClassLoader()); - - run(); - - try { - synchronized (waitObject) { - waitObject.wait(); - } - } catch (InterruptedException ex) { - } - - reportStatus(Winsvc.SERVICE_STOPPED, WinError.NO_ERROR, 0); - - // Avoid returning from ServiceMain, which will cause a crash - // See http://support.microsoft.com/kb/201349, which recommends - // having init() wait for this thread. - // Waiting on this thread in init() won't fix the crash, though. - - System.exit(0); - } - - } - - private class ServiceControl implements HandlerEx { - - public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext) { - switch (dwControl) { - case Winsvc.SERVICE_CONTROL_STOP: - case Winsvc.SERVICE_CONTROL_SHUTDOWN: - reportStatus(Winsvc.SERVICE_STOP_PENDING, WinError.NO_ERROR, 5000); - synchronized (waitObject) { - waitObject.notifyAll(); - } - break; - default: - break; - } - return WinError.NO_ERROR; - } - - } - -} diff --git a/src/org/traccar/WrapperContext.java b/src/org/traccar/WrapperContext.java deleted file mode 100644 index 372d3c60d..000000000 --- a/src/org/traccar/WrapperContext.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 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 deleted file mode 100644 index ca33d021f..000000000 --- a/src/org/traccar/WrapperInboundHandler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 ChannelInboundHandler getWrappedHandler() { - return 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 deleted file mode 100644 index 0136c5b22..000000000 --- a/src/org/traccar/WrapperOutboundHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 ChannelOutboundHandler getWrappedHandler() { - return 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/AsyncSocket.java b/src/org/traccar/api/AsyncSocket.java deleted file mode 100644 index 906d16b5b..000000000 --- a/src/org/traccar/api/AsyncSocket.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.core.JsonProcessingException; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.database.ConnectionManager; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.UpdateListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(AsyncSocket.class); - - private static final String KEY_DEVICES = "devices"; - private static final String KEY_POSITIONS = "positions"; - private static final String KEY_EVENTS = "events"; - - private long userId; - - public AsyncSocket(long userId) { - this.userId = userId; - } - - @Override - public void onWebSocketConnect(Session session) { - super.onWebSocketConnect(session); - - Map<String, Collection<?>> data = new HashMap<>(); - data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); - sendData(data); - - Context.getConnectionManager().addListener(userId, this); - } - - @Override - public void onWebSocketClose(int statusCode, String reason) { - super.onWebSocketClose(statusCode, reason); - - Context.getConnectionManager().removeListener(userId, this); - } - - @Override - public void onUpdateDevice(Device device) { - Map<String, Collection<?>> data = new HashMap<>(); - data.put(KEY_DEVICES, Collections.singletonList(device)); - sendData(data); - } - - @Override - public void onUpdatePosition(Position position) { - Map<String, Collection<?>> data = new HashMap<>(); - data.put(KEY_POSITIONS, Collections.singletonList(position)); - sendData(data); - } - - @Override - public void onUpdateEvent(Event event) { - Map<String, Collection<?>> data = new HashMap<>(); - data.put(KEY_EVENTS, Collections.singletonList(event)); - sendData(data); - } - - private void sendData(Map<String, Collection<?>> data) { - if (!data.isEmpty() && isConnected()) { - try { - getRemote().sendString(Context.getObjectMapper().writeValueAsString(data), null); - } catch (JsonProcessingException e) { - LOGGER.warn("Socket JSON formatting error", e); - } - } - } -} diff --git a/src/org/traccar/api/AsyncSocketServlet.java b/src/org/traccar/api/AsyncSocketServlet.java deleted file mode 100644 index 9318b6fc6..000000000 --- a/src/org/traccar/api/AsyncSocketServlet.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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; - -import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; -import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; -import org.eclipse.jetty.websocket.servlet.WebSocketCreator; -import org.eclipse.jetty.websocket.servlet.WebSocketServlet; -import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; -import org.traccar.Context; -import org.traccar.api.resource.SessionResource; - -public class AsyncSocketServlet extends WebSocketServlet { - - private static final long ASYNC_TIMEOUT = 10 * 60 * 1000; - - @Override - public void configure(WebSocketServletFactory factory) { - factory.getPolicy().setIdleTimeout(Context.getConfig().getLong("web.timeout", ASYNC_TIMEOUT)); - factory.setCreator(new WebSocketCreator() { - @Override - public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { - if (req.getSession() != null) { - long userId = (Long) req.getSession().getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(userId); - } else { - return null; - } - } - }); - } - -} diff --git a/src/org/traccar/api/BaseObjectResource.java b/src/org/traccar/api/BaseObjectResource.java deleted file mode 100644 index 7de6a3877..000000000 --- a/src/org/traccar/api/BaseObjectResource.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2017 - 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. - * 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; - -import java.sql.SQLException; -import java.util.Set; - -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; -import org.traccar.database.ExtendedObjectManager; -import org.traccar.database.ManagableObjects; -import org.traccar.database.SimpleObjectManager; -import org.traccar.helper.LogAction; -import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; -import org.traccar.model.Command; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.GroupedModel; -import org.traccar.model.ScheduledModel; -import org.traccar.model.User; - -public abstract class BaseObjectResource<T extends BaseModel> extends BaseResource { - - private Class<T> baseClass; - - public BaseObjectResource(Class<T> baseClass) { - this.baseClass = baseClass; - } - - protected final Class<T> getBaseClass() { - return baseClass; - } - - protected final Set<Long> getSimpleManagerItems(BaseObjectManager<T> manager, boolean all, long userId) { - Set<Long> result = null; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = manager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = ((ManagableObjects) manager).getManagedItems(getUserId()); - } - } else { - if (userId == 0) { - userId = getUserId(); - } - Context.getPermissionsManager().checkUser(getUserId(), userId); - result = ((ManagableObjects) manager).getUserItems(userId); - } - return result; - } - - @POST - public Response add(T entity) throws SQLException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - Context.getPermissionsManager().checkDeviceLimit(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } - - BaseObjectManager<T> manager = Context.getManager(baseClass); - manager.addItem(entity); - LogAction.create(getUserId(), entity); - - Context.getDataManager().linkObject(User.class, getUserId(), baseClass, entity.getId(), true); - LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); - - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager<T>) manager).refreshUserItems(); - } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - return Response.ok(entity).build(); - } - - @Path("{id}") - @PUT - public Response update(T entity) throws SQLException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(User.class)) { - User before = Context.getPermissionsManager().getUser(entity.getId()); - Context.getPermissionsManager().checkUserUpdate(getUserId(), before, (User) entity); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), entity.getId()); - - Context.getManager(baseClass).updateItem(entity); - LogAction.edit(getUserId(), entity); - - if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - return Response.ok(entity).build(); - } - - @Path("{id}") - @DELETE - public Response remove(@PathParam("id") long id) throws SQLException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); - - BaseObjectManager<T> manager = Context.getManager(baseClass); - manager.removeItem(id); - LogAction.remove(getUserId(), baseClass, id); - - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager<T>) manager).refreshUserItems(); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager<T>) manager).refreshExtendedPermissions(); - } - } - if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { - if (baseClass.equals(Group.class)) { - Context.getGroupsManager().updateGroupCache(true); - Context.getDeviceManager().updateDeviceCache(true); - } - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - if (baseClass.equals(User.class)) { - Context.getPermissionsManager().refreshAllUsersPermissions(); - } else { - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - } else if (baseClass.equals(Calendar.class)) { - Context.getGeofenceManager().refreshItems(); - Context.getNotificationManager().refreshItems(); - } - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/api/BaseResource.java b/src/org/traccar/api/BaseResource.java deleted file mode 100644 index cc272df9c..000000000 --- a/src/org/traccar/api/BaseResource.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import javax.ws.rs.core.SecurityContext; - -public class BaseResource { - - @javax.ws.rs.core.Context - private SecurityContext securityContext; - - protected long getUserId() { - UserPrincipal principal = (UserPrincipal) securityContext.getUserPrincipal(); - if (principal != null) { - return principal.getUserId(); - } - return 0; - } -} diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java deleted file mode 100644 index 227f80609..000000000 --- a/src/org/traccar/api/CorsResponseFilter.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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; - -import io.netty.handler.codec.http.HttpHeaderNames; -import org.traccar.Context; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; -import java.io.IOException; - -public class CorsResponseFilter implements ContainerResponseFilter { - - private static final String ORIGIN_ALL = "*"; - private static final String HEADERS_ALL = "origin, content-type, accept, authorization"; - private static final String METHODS_ALL = "GET, POST, PUT, DELETE, OPTIONS"; - - @Override - public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { - 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(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS.toString())) { - response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS.toString(), true); - } - - 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(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(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), ORIGIN_ALL); - } else if (allowed == null || allowed.equals(ORIGIN_ALL) || allowed.contains(origin)) { - response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), origin); - } - } - } - -} diff --git a/src/org/traccar/api/ExtendedObjectResource.java b/src/org/traccar/api/ExtendedObjectResource.java deleted file mode 100644 index 007a7b1bd..000000000 --- a/src/org/traccar/api/ExtendedObjectResource.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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; - -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.ws.rs.GET; -import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.ExtendedObjectManager; -import org.traccar.model.BaseModel; - -public class ExtendedObjectResource<T extends BaseModel> extends BaseObjectResource<T> { - - public ExtendedObjectResource(Class<T> baseClass) { - super(baseClass); - } - - @GET - public Collection<T> get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("groupId") long groupId, - @QueryParam("deviceId") long deviceId, @QueryParam("refresh") boolean refresh) throws SQLException { - - ExtendedObjectManager<T> manager = (ExtendedObjectManager<T>) Context.getManager(getBaseClass()); - if (refresh) { - manager.refreshItems(); - } - - Set<Long> result = new HashSet<>(getSimpleManagerItems(manager, all, userId)); - - if (groupId != 0) { - Context.getPermissionsManager().checkGroup(getUserId(), groupId); - result.retainAll(manager.getGroupItems(groupId)); - } - - if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - result.retainAll(manager.getDeviceItems(deviceId)); - } - return manager.getItems(result); - - } - -} diff --git a/src/org/traccar/api/MediaFilter.java b/src/org/traccar/api/MediaFilter.java deleted file mode 100644 index 53539770f..000000000 --- a/src/org/traccar/api/MediaFilter.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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; - -import java.io.IOException; -import java.sql.SQLException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.api.resource.SessionResource; -import org.traccar.database.StatisticsManager; -import org.traccar.helper.Log; -import org.traccar.model.Device; - -public class MediaFilter implements Filter { - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - HttpServletResponse httpResponse = (HttpServletResponse) response; - try { - HttpSession session = ((HttpServletRequest) request).getSession(false); - Long userId = null; - if (session != null) { - userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); - if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); - } - } - if (userId == null) { - httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - - String path = ((HttpServletRequest) request).getPathInfo(); - String[] parts = path.split("/"); - if (parts.length < 2 || parts.length == 2 && !path.endsWith("/")) { - Context.getPermissionsManager().checkAdmin(userId); - } else { - Device device = Context.getDeviceManager().getByUniqueId(parts[1]); - if (device != null) { - Context.getPermissionsManager().checkDevice(userId, device.getId()); - } else { - httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND); - return; - } - } - - chain.doFilter(request, response); - } catch (SecurityException e) { - httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); - httpResponse.getWriter().println(Log.exceptionStack(e)); - } catch (SQLException e) { - httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); - httpResponse.getWriter().println(Log.exceptionStack(e)); - } - } - - @Override - public void destroy() { - } - -} diff --git a/src/org/traccar/api/ObjectMapperProvider.java b/src/org/traccar/api/ObjectMapperProvider.java deleted file mode 100644 index f81b20917..000000000 --- a/src/org/traccar/api/ObjectMapperProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Context; - -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; - -@Provider -public class ObjectMapperProvider implements ContextResolver<ObjectMapper> { - - @Override - public ObjectMapper getContext(Class<?> type) { - return Context.getObjectMapper(); - } - -} diff --git a/src/org/traccar/api/ResourceErrorHandler.java b/src/org/traccar/api/ResourceErrorHandler.java deleted file mode 100644 index 1d618b08d..000000000 --- a/src/org/traccar/api/ResourceErrorHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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; - -import org.traccar.helper.Log; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; - -public class ResourceErrorHandler implements ExceptionMapper<Exception> { - - @Override - public Response toResponse(Exception e) { - if (e instanceof WebApplicationException) { - WebApplicationException exception = (WebApplicationException) e; - String message; - if (exception.getCause() != null) { - message = Log.exceptionStack(exception.getCause()); - } else { - message = Log.exceptionStack(exception); - } - return Response.fromResponse(exception.getResponse()).entity(message).build(); - } else { - return Response.status(Response.Status.BAD_REQUEST).entity(Log.exceptionStack(e)).build(); - } - } - -} diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java deleted file mode 100644 index 33b6b37df..000000000 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.api.resource.SessionResource; -import org.traccar.database.StatisticsManager; -import org.traccar.helper.DataConverter; -import org.traccar.model.User; - -import javax.annotation.security.PermitAll; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.container.ResourceInfo; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; -import java.lang.reflect.Method; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; - -public class SecurityRequestFilter implements ContainerRequestFilter { - - private static final Logger LOGGER = LoggerFactory.getLogger(SecurityRequestFilter.class); - - public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - public static final String BASIC_REALM = "Basic realm=\"api\""; - public static final String X_REQUESTED_WITH = "X-Requested-With"; - public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; - - public static String[] decodeBasicAuth(String auth) { - auth = auth.replaceFirst("[B|b]asic ", ""); - byte[] decodedBytes = DataConverter.parseBase64(auth); - if (decodedBytes != null && decodedBytes.length > 0) { - return new String(decodedBytes, StandardCharsets.US_ASCII).split(":", 2); - } - return null; - } - - @javax.ws.rs.core.Context - private HttpServletRequest request; - - @javax.ws.rs.core.Context - private ResourceInfo resourceInfo; - - @Override - public void filter(ContainerRequestContext requestContext) { - - if (requestContext.getMethod().equals("OPTIONS")) { - return; - } - - SecurityContext securityContext = null; - - try { - - String authHeader = requestContext.getHeaderString(AUTHORIZATION_HEADER); - if (authHeader != null) { - - try { - String[] auth = decodeBasicAuth(authHeader); - User user = Context.getPermissionsManager().login(auth[0], auth[1]); - if (user != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); - securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); - } - } catch (SQLException e) { - throw new WebApplicationException(e); - } - - } else if (request.getSession() != null) { - - Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); - if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); - securityContext = new UserSecurityContext(new UserPrincipal(userId)); - } - - } - - } catch (SecurityException e) { - LOGGER.warn("Authentication error", e); - } - - if (securityContext != null) { - requestContext.setSecurityContext(securityContext); - } else { - Method method = resourceInfo.getResourceMethod(); - if (!method.isAnnotationPresent(PermitAll.class)) { - Response.ResponseBuilder responseBuilder = Response.status(Response.Status.UNAUTHORIZED); - if (!XML_HTTP_REQUEST.equals(request.getHeader(X_REQUESTED_WITH))) { - responseBuilder.header(WWW_AUTHENTICATE, BASIC_REALM); - } - throw new WebApplicationException(responseBuilder.build()); - } - } - - } - -} diff --git a/src/org/traccar/api/SimpleObjectResource.java b/src/org/traccar/api/SimpleObjectResource.java deleted file mode 100644 index a7fcae0e7..000000000 --- a/src/org/traccar/api/SimpleObjectResource.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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; - -import java.sql.SQLException; -import java.util.Collection; - -import javax.ws.rs.GET; -import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; -import org.traccar.model.BaseModel; - -public class SimpleObjectResource<T extends BaseModel> extends BaseObjectResource<T> { - - public SimpleObjectResource(Class<T> baseClass) { - super(baseClass); - } - - @GET - public Collection<T> get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { - - BaseObjectManager<T> manager = Context.getManager(getBaseClass()); - return manager.getItems(getSimpleManagerItems(manager, all, userId)); - } - -} diff --git a/src/org/traccar/api/UserPrincipal.java b/src/org/traccar/api/UserPrincipal.java deleted file mode 100644 index 80e92c2dd..000000000 --- a/src/org/traccar/api/UserPrincipal.java +++ /dev/null @@ -1,37 +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.api; - -import java.security.Principal; - -public class UserPrincipal implements Principal { - - private long userId; - - public UserPrincipal(long userId) { - this.userId = userId; - } - - public Long getUserId() { - return userId; - } - - @Override - public String getName() { - return null; - } - -} diff --git a/src/org/traccar/api/UserSecurityContext.java b/src/org/traccar/api/UserSecurityContext.java deleted file mode 100644 index 55c0621bc..000000000 --- a/src/org/traccar/api/UserSecurityContext.java +++ /dev/null @@ -1,49 +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.api; - -import javax.ws.rs.core.SecurityContext; -import java.security.Principal; - -public class UserSecurityContext implements SecurityContext { - - private UserPrincipal principal; - - public UserSecurityContext(UserPrincipal principal) { - this.principal = principal; - } - - @Override - public Principal getUserPrincipal() { - return principal; - } - - @Override - public boolean isUserInRole(String role) { - return true; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public String getAuthenticationScheme() { - return BASIC_AUTH; - } - -} diff --git a/src/org/traccar/api/resource/AttributeResource.java b/src/org/traccar/api/resource/AttributeResource.java deleted file mode 100644 index de69d871c..000000000 --- a/src/org/traccar/api/resource/AttributeResource.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 - 2019 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. - * 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 java.sql.SQLException; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.api.ExtendedObjectResource; -import org.traccar.model.Attribute; -import org.traccar.model.Position; -import org.traccar.handler.ComputedAttributesHandler; - -@Path("attributes/computed") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class AttributeResource extends ExtendedObjectResource<Attribute> { - - public AttributeResource() { - super(Attribute.class); - } - - @POST - @Path("test") - public Response test(@QueryParam("deviceId") long deviceId, Attribute entity) { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - Position last = Context.getIdentityManager().getLastPosition(deviceId); - if (last != null) { - Object result = new ComputedAttributesHandler( - Context.getConfig(), - Context.getIdentityManager(), - Context.getAttributesManager()).computeAttribute(entity, last); - if (result != null) { - switch (entity.getType()) { - case "number": - Number numberValue = (Number) result; - return Response.ok(numberValue).build(); - case "boolean": - Boolean booleanValue = (Boolean) result; - return Response.ok(booleanValue).build(); - default: - return Response.ok(result.toString()).build(); - } - } else { - return Response.noContent().build(); - } - } else { - throw new IllegalArgumentException("Device has no last position"); - } - } - - @POST - public Response add(Attribute entity) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return super.add(entity); - } - - @Path("{id}") - @PUT - public Response update(Attribute entity) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return super.update(entity); - } - - @Path("{id}") - @DELETE - public Response remove(@PathParam("id") long id) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return super.remove(id); - } - -} diff --git a/src/org/traccar/api/resource/CalendarResource.java b/src/org/traccar/api/resource/CalendarResource.java deleted file mode 100644 index 9399c34a5..000000000 --- a/src/org/traccar/api/resource/CalendarResource.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.SimpleObjectResource; -import org.traccar.model.Calendar; - -@Path("calendars") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class CalendarResource extends SimpleObjectResource<Calendar> { - - public CalendarResource() { - super(Calendar.class); - } - -} diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java deleted file mode 100644 index 703638701..000000000 --- a/src/org/traccar/api/resource/CommandResource.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) - * Copyright 2017 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 org.traccar.Context; -import org.traccar.api.ExtendedObjectResource; -import org.traccar.database.CommandsManager; -import org.traccar.model.Command; -import org.traccar.model.Typed; - -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Path("commands") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class CommandResource extends ExtendedObjectResource<Command> { - - public CommandResource() { - super(Command.class); - } - - @GET - @Path("send") - public Collection<Command> get(@QueryParam("deviceId") long deviceId) throws SQLException { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - CommandsManager commandsManager = Context.getCommandsManager(); - Set<Long> result = new HashSet<>(commandsManager.getUserItems(getUserId())); - result.retainAll(commandsManager.getSupportedCommands(deviceId)); - return commandsManager.getItems(result); - } - - @POST - @Path("send") - public Response send(Command entity) throws Exception { - Context.getPermissionsManager().checkReadonly(getUserId()); - long deviceId = entity.getDeviceId(); - long id = entity.getId(); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - if (id != 0) { - Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id); - Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id); - } else { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - if (!Context.getCommandsManager().sendCommand(entity)) { - return Response.accepted(entity).build(); - } - return Response.ok(entity).build(); - } - - @GET - @Path("types") - public Collection<Typed> get(@QueryParam("deviceId") long deviceId, - @QueryParam("textChannel") boolean textChannel) { - if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getCommandsManager().getCommandTypes(deviceId, textChannel); - } else { - return Context.getCommandsManager().getAllCommandTypes(); - } - } -} diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java deleted file mode 100644 index f9c9a139d..000000000 --- a/src/org/traccar/api/resource/DeviceResource.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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. - * 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 org.traccar.Context; -import org.traccar.api.BaseObjectResource; -import org.traccar.database.DeviceManager; -import org.traccar.helper.LogAction; -import org.traccar.model.Device; -import org.traccar.model.DeviceAccumulators; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -@Path("devices") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class DeviceResource extends BaseObjectResource<Device> { - - public DeviceResource() { - super(Device.class); - } - - @GET - public Collection<Device> get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId, - @QueryParam("uniqueId") List<String> uniqueIds, - @QueryParam("id") List<Long> deviceIds) throws SQLException { - DeviceManager deviceManager = Context.getDeviceManager(); - Set<Long> result = null; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = deviceManager.getManagedItems(getUserId()); - } - } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { - if (userId == 0) { - userId = getUserId(); - } - Context.getPermissionsManager().checkUser(getUserId(), userId); - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllUserItems(userId); - } else { - result = deviceManager.getUserItems(userId); - } - } else { - result = new HashSet<>(); - for (String uniqueId : uniqueIds) { - Device device = deviceManager.getByUniqueId(uniqueId); - Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); - result.add(device.getId()); - } - for (Long deviceId : deviceIds) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - result.add(deviceId); - } - } - return deviceManager.getItems(result); - } - - @Path("{id}/accumulators") - @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws SQLException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkManager(getUserId()); - Context.getPermissionsManager().checkPermission(Device.class, getUserId(), entity.getDeviceId()); - } - Context.getDeviceManager().resetDeviceAccumulators(entity); - LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId()); - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/api/resource/DriverResource.java b/src/org/traccar/api/resource/DriverResource.java deleted file mode 100644 index 91aa54c5e..000000000 --- a/src/org/traccar/api/resource/DriverResource.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.Driver; - -@Path("drivers") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class DriverResource extends ExtendedObjectResource<Driver> { - - public DriverResource() { - super(Driver.class); - } - -} diff --git a/src/org/traccar/api/resource/EventResource.java b/src/org/traccar/api/resource/EventResource.java deleted file mode 100644 index e0ccf7020..000000000 --- a/src/org/traccar/api/resource/EventResource.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.traccar.api.resource; - -import java.sql.SQLException; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -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) -@Consumes(MediaType.APPLICATION_JSON) - -public class EventResource extends BaseResource { - - @Path("{id}") - @GET - public Event get(@PathParam("id") long id) throws SQLException { - Event event = Context.getDataManager().getObject(Event.class, id); - Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); - 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/GeofenceResource.java b/src/org/traccar/api/resource/GeofenceResource.java deleted file mode 100644 index 58f2c188c..000000000 --- a/src/org/traccar/api/resource/GeofenceResource.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 org.traccar.api.ExtendedObjectResource; -import org.traccar.model.Geofence; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -@Path("geofences") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class GeofenceResource extends ExtendedObjectResource<Geofence> { - - public GeofenceResource() { - super(Geofence.class); - } - -} diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java deleted file mode 100644 index fcea15d0a..000000000 --- a/src/org/traccar/api/resource/GroupResource.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 org.traccar.api.SimpleObjectResource; -import org.traccar.model.Group; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -@Path("groups") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class GroupResource extends SimpleObjectResource<Group> { - - public GroupResource() { - super(Group.class); - } - -} diff --git a/src/org/traccar/api/resource/MaintenanceResource.java b/src/org/traccar/api/resource/MaintenanceResource.java deleted file mode 100644 index fa1b359ce..000000000 --- a/src/org/traccar/api/resource/MaintenanceResource.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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("maintenance") -@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/api/resource/NotificationResource.java b/src/org/traccar/api/resource/NotificationResource.java deleted file mode 100644 index 9631a52b7..000000000 --- a/src/org/traccar/api/resource/NotificationResource.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - * 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 java.util.Collection; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.api.ExtendedObjectResource; -import org.traccar.model.Event; -import org.traccar.model.Notification; -import org.traccar.model.Typed; -import org.traccar.notification.MessageException; - - -@Path("notifications") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class NotificationResource extends ExtendedObjectResource<Notification> { - - public NotificationResource() { - super(Notification.class); - } - - @GET - @Path("types") - public Collection<Typed> get() { - return Context.getNotificationManager().getAllNotificationTypes(); - } - - @GET - @Path("notificators") - public Collection<Typed> getNotificators() { - return Context.getNotificatorManager().getAllNotificatorTypes(); - } - - @POST - @Path("test") - public Response testMessage() throws MessageException, InterruptedException { - for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { - Context.getNotificatorManager() - .getNotificator(method.getType()).sendSync(getUserId(), new Event("test", 0), null); - } - return Response.noContent().build(); - } - - @POST - @Path("test/{notificator}") - public Response testMessage(@PathParam("notificator") String notificator) - throws MessageException, InterruptedException { - Context.getNotificatorManager().getNotificator(notificator).sendSync(getUserId(), new Event("test", 0), null); - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/api/resource/PermissionsResource.java b/src/org/traccar/api/resource/PermissionsResource.java deleted file mode 100644 index b89d9d376..000000000 --- a/src/org/traccar/api/resource/PermissionsResource.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.sql.SQLException; -import java.util.LinkedHashMap; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.LogAction; -import org.traccar.model.Device; -import org.traccar.model.Permission; -import org.traccar.model.User; - -@Path("permissions") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class PermissionsResource extends BaseResource { - - private void checkPermission(Permission permission, boolean link) { - if (!link && permission.getOwnerClass().equals(User.class) - && permission.getPropertyClass().equals(Device.class)) { - if (getUserId() != permission.getOwnerId()) { - Context.getPermissionsManager().checkUser(getUserId(), permission.getOwnerId()); - } else { - Context.getPermissionsManager().checkAdmin(getUserId()); - } - } else { - Context.getPermissionsManager().checkPermission( - permission.getOwnerClass(), getUserId(), permission.getOwnerId()); - } - Context.getPermissionsManager().checkPermission( - permission.getPropertyClass(), getUserId(), permission.getPropertyId()); - } - - @POST - public Response add(LinkedHashMap<String, Long> entity) throws SQLException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); - Permission permission = new Permission(entity); - checkPermission(permission, true); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), true); - LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); - Context.getPermissionsManager().refreshPermissions(permission); - return Response.noContent().build(); - } - - @DELETE - public Response remove(LinkedHashMap<String, Long> entity) throws SQLException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); - Permission permission = new Permission(entity); - checkPermission(permission, false); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), false); - LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); - Context.getPermissionsManager().refreshPermissions(permission); - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java deleted file mode 100644 index c031b842f..000000000 --- a/src/org/traccar/api/resource/PositionResource.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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 org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.DateUtil; -import org.traccar.model.Position; -import org.traccar.web.CsvBuilder; -import org.traccar.web.GpxBuilder; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@Path("positions") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class PositionResource extends BaseResource { - - public static final String TEXT_CSV = "text/csv"; - public static final String CONTENT_DISPOSITION_VALUE_CSV = "attachment; filename=positions.csv"; - public static final String GPX = "application/gpx+xml"; - public static final String CONTENT_DISPOSITION_VALUE_GPX = "attachment; filename=positions.gpx"; - - @GET - public Collection<Position> getJson( - @QueryParam("deviceId") long deviceId, @QueryParam("id") List<Long> positionIds, - @QueryParam("from") String from, @QueryParam("to") String to) - throws SQLException { - if (!positionIds.isEmpty()) { - ArrayList<Position> positions = new ArrayList<>(); - for (Long positionId : positionIds) { - Position position = Context.getDataManager().getObject(Position.class, positionId); - Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); - positions.add(position); - } - return positions; - } else if (deviceId == 0) { - return Context.getDeviceManager().getInitialState(getUserId()); - } else { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getDataManager().getPositions( - deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - } - - @GET - @Produces(TEXT_CSV) - public Response getCsv( - @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) - throws SQLException { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - CsvBuilder csv = new CsvBuilder(); - csv.addHeaderLine(new Position()); - csv.addArray(Context.getDataManager().getPositions( - deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to))); - return Response.ok(csv.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_CSV).build(); - } - - @GET - @Produces(GPX) - public Response getGpx( - @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) - throws SQLException { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getById(deviceId).getName()); - gpx.addPositions(Context.getDataManager().getPositions( - deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to))); - return Response.ok(gpx.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_GPX).build(); - } - -} diff --git a/src/org/traccar/api/resource/ReportResource.java b/src/org/traccar/api/resource/ReportResource.java deleted file mode 100644 index d371cf987..000000000 --- a/src/org/traccar/api/resource/ReportResource.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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. - * 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 java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.sql.SQLException; -import java.util.Collection; -import java.util.List; - -import javax.activation.DataHandler; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.util.ByteArrayDataSource; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.DateUtil; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.Events; -import org.traccar.reports.Summary; -import org.traccar.reports.Trips; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.SummaryReport; -import org.traccar.reports.model.TripReport; -import org.traccar.reports.Route; -import org.traccar.reports.Stops; - -@Path("reports") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class ReportResource extends BaseResource { - - private static final Logger LOGGER = LoggerFactory.getLogger(ReportResource.class); - - private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; - - private interface ReportExecutor { - void execute(ByteArrayOutputStream stream) throws SQLException, IOException; - } - - private Response executeReport( - long userId, boolean mail, ReportExecutor executor) throws SQLException, IOException { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); - if (mail) { - new Thread(() -> { - try { - executor.execute(stream); - - MimeBodyPart attachment = new MimeBodyPart(); - - attachment.setFileName("report.xlsx"); - attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( - stream.toByteArray(), "application/octet-stream"))); - - Context.getMailManager().sendMessage( - userId, "Report", "The report is in the attachment.", attachment); - } catch (SQLException | IOException | MessagingException e) { - LOGGER.warn("Report failed", e); - } - }).start(); - return Response.noContent().build(); - } else { - executor.execute(stream); - return Response.ok(stream.toByteArray()) - .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); - } - } - - @Path("route") - @GET - public Collection<Position> getRoute( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - return Route.getObjects(getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - - @Path("route") - @GET - @Produces(XLSX) - public Response getRouteExcel( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { - return executeReport(getUserId(), mail, stream -> { - Route.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - }); - } - - @Path("events") - @GET - public Collection<Event> getEvents( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("type") final List<String> types, - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - return Events.getObjects(getUserId(), deviceIds, groupIds, types, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - - @Path("events") - @GET - @Produces(XLSX) - public Response getEventsExcel( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("type") final List<String> types, - @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { - return executeReport(getUserId(), mail, stream -> { - Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - }); - } - - @Path("summary") - @GET - public Collection<SummaryReport> getSummary( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - return Summary.getObjects(getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - - @Path("summary") - @GET - @Produces(XLSX) - public Response getSummaryExcel( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { - return executeReport(getUserId(), mail, stream -> { - Summary.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - }); - } - - @Path("trips") - @GET - @Produces(MediaType.APPLICATION_JSON) - public Collection<TripReport> getTrips( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - return Trips.getObjects(getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - - @Path("trips") - @GET - @Produces(XLSX) - public Response getTripsExcel( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { - return executeReport(getUserId(), mail, stream -> { - Trips.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - }); - } - - @Path("stops") - @GET - @Produces(MediaType.APPLICATION_JSON) - public Collection<StopReport> getStops( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - return Stops.getObjects(getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - - @Path("stops") - @GET - @Produces(XLSX) - public Response getStopsExcel( - @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, - @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { - return executeReport(getUserId(), mail, stream -> { - Stops.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); - }); - } - -} diff --git a/src/org/traccar/api/resource/ServerResource.java b/src/org/traccar/api/resource/ServerResource.java deleted file mode 100644 index e7cad2a0c..000000000 --- a/src/org/traccar/api/resource/ServerResource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.LogAction; -import org.traccar.model.Server; - -import javax.annotation.security.PermitAll; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.sql.SQLException; - -@Path("server") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class ServerResource extends BaseResource { - - @PermitAll - @GET - public Server get() throws SQLException { - return Context.getPermissionsManager().getServer(); - } - - @PUT - public Response update(Server entity) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().updateServer(entity); - LogAction.edit(getUserId(), entity); - return Response.ok(entity).build(); - } - - @Path("geocode") - @GET - public String geocode(@QueryParam("latitude") double latitude, @QueryParam("longitude") double longitude) { - if (Context.getGeocoder() != null) { - return Context.getGeocoder().getAddress(latitude, longitude, null); - } else { - throw new RuntimeException("Reverse geocoding is not enabled"); - } - } - -} diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java deleted file mode 100644 index fd331c766..000000000 --- a/src/org/traccar/api/resource/SessionResource.java +++ /dev/null @@ -1,120 +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.api.resource; - -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.DataConverter; -import org.traccar.helper.LogAction; -import org.traccar.model.User; - -import javax.annotation.security.PermitAll; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; - -@Path("session") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_FORM_URLENCODED) -public class SessionResource extends BaseResource { - - public static final String USER_ID_KEY = "userId"; - public static final String USER_COOKIE_KEY = "user"; - public static final String PASS_COOKIE_KEY = "password"; - - @javax.ws.rs.core.Context - private HttpServletRequest request; - - @PermitAll - @GET - public User get(@QueryParam("token") String token) throws SQLException, UnsupportedEncodingException { - Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); - if (userId == null) { - Cookie[] cookies = request.getCookies(); - String email = null, password = null; - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equals(USER_COOKIE_KEY)) { - byte[] emailBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); - email = new String(emailBytes, StandardCharsets.UTF_8); - } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { - byte[] passwordBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); - password = new String(passwordBytes, StandardCharsets.UTF_8); - } - } - } - if (email != null && password != null) { - User user = Context.getPermissionsManager().login(email, password); - if (user != null) { - userId = user.getId(); - request.getSession().setAttribute(USER_ID_KEY, userId); - } - } else if (token != null) { - User user = Context.getUsersManager().getUserByToken(token); - if (user != null) { - userId = user.getId(); - request.getSession().setAttribute(USER_ID_KEY, userId); - } - } - } - - if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - return Context.getPermissionsManager().getUser(userId); - } else { - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); - } - } - - @PermitAll - @POST - public User add( - @FormParam("email") String email, @FormParam("password") String password) throws SQLException { - User user = Context.getPermissionsManager().login(email, password); - if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId()); - return user; - } else { - throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); - } - } - - @DELETE - public Response remove() { - LogAction.logout(getUserId()); - request.getSession().removeAttribute(USER_ID_KEY); - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/api/resource/StatisticsResource.java b/src/org/traccar/api/resource/StatisticsResource.java deleted file mode 100644 index e801d4ff3..000000000 --- a/src/org/traccar/api/resource/StatisticsResource.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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 org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.DateUtil; -import org.traccar.model.Statistics; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import java.sql.SQLException; -import java.util.Collection; - -@Path("statistics") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class StatisticsResource extends BaseResource { - - @GET - public Collection<Statistics> get( - @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return Context.getDataManager().getStatistics(DateUtil.parseDate(from), DateUtil.parseDate(to)); - } - -} diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java deleted file mode 100644 index 0b42d8d92..000000000 --- a/src/org/traccar/api/resource/UserResource.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 org.traccar.Context; -import org.traccar.api.BaseObjectResource; -import org.traccar.database.UsersManager; -import org.traccar.helper.LogAction; -import org.traccar.model.ManagedUser; -import org.traccar.model.User; - -import javax.annotation.security.PermitAll; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.sql.SQLException; -import java.util.Collection; -import java.util.Date; -import java.util.Set; - -@Path("users") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class UserResource extends BaseObjectResource<User> { - - public UserResource() { - super(User.class); - } - - @GET - public Collection<User> get(@QueryParam("userId") long userId) throws SQLException { - UsersManager usersManager = Context.getUsersManager(); - Set<Long> result = null; - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - if (userId != 0) { - result = usersManager.getUserItems(userId); - } else { - result = usersManager.getAllItems(); - } - } else if (Context.getPermissionsManager().getUserManager(getUserId())) { - result = usersManager.getManagedItems(getUserId()); - } else { - throw new SecurityException("Admin or manager access required"); - } - return usersManager.getItems(result); - } - - @Override - @PermitAll - @POST - public Response add(User entity) throws SQLException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkUserUpdate(getUserId(), new User(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getPermissionsManager().checkUserLimit(getUserId()); - } else { - Context.getPermissionsManager().checkRegistration(getUserId()); - entity.setDeviceLimit(Context.getConfig().getInteger("users.defaultDeviceLimit", -1)); - int expirationDays = Context.getConfig().getInteger("users.defaultExpirationDays"); - if (expirationDays > 0) { - entity.setExpirationTime( - new Date(System.currentTimeMillis() + (long) expirationDays * 24 * 3600 * 1000)); - } - } - } - Context.getUsersManager().addItem(entity); - LogAction.create(getUserId(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true); - LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); - } - Context.getUsersManager().refreshUserItems(); - return Response.ok(entity).build(); - } - -} diff --git a/src/org/traccar/config/Config.java b/src/org/traccar/config/Config.java deleted file mode 100644 index d8f2a0e99..000000000 --- a/src/org/traccar/config/Config.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.config; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.InvalidPropertiesFormatException; -import java.util.Properties; - -public class Config { - - private final Properties properties = new Properties(); - - private boolean useEnvironmentVariables; - - public Config() { - } - - public Config(String file) throws IOException { - try { - Properties mainProperties = new Properties(); - try (InputStream inputStream = new FileInputStream(file)) { - mainProperties.loadFromXML(inputStream); - } - - String defaultConfigFile = mainProperties.getProperty("config.default"); - if (defaultConfigFile != null) { - try (InputStream inputStream = new FileInputStream(defaultConfigFile)) { - properties.loadFromXML(inputStream); - } - } - - properties.putAll(mainProperties); // override defaults - - useEnvironmentVariables = Boolean.parseBoolean(System.getenv("CONFIG_USE_ENVIRONMENT_VARIABLES")) - || Boolean.parseBoolean(properties.getProperty("config.useEnvironmentVariables")); - } catch (InvalidPropertiesFormatException e) { - throw new RuntimeException("Configuration file is not a valid XML document", e); - } - } - - public boolean hasKey(ConfigKey key) { - return hasKey(key.getKey()); - } - - @Deprecated - public boolean hasKey(String key) { - return useEnvironmentVariables && System.getenv().containsKey(getEnvironmentVariableName(key)) - || properties.containsKey(key); - } - - public String getString(ConfigKey key) { - return getString(key.getKey()); - } - - @Deprecated - public String getString(String key) { - if (useEnvironmentVariables) { - String value = System.getenv(getEnvironmentVariableName(key)); - if (value != null && !value.isEmpty()) { - return value; - } - } - return properties.getProperty(key); - } - - public String getString(ConfigKey key, String defaultValue) { - return getString(key.getKey(), defaultValue); - } - - @Deprecated - public String getString(String key, String defaultValue) { - return hasKey(key) ? getString(key) : defaultValue; - } - - public boolean getBoolean(ConfigKey key) { - return getBoolean(key.getKey()); - } - - @Deprecated - public boolean getBoolean(String key) { - return Boolean.parseBoolean(getString(key)); - } - - public int getInteger(ConfigKey key) { - return getInteger(key.getKey()); - } - - @Deprecated - public int getInteger(String key) { - return getInteger(key, 0); - } - - public int getInteger(ConfigKey key, int defaultValue) { - return getInteger(key.getKey(), defaultValue); - } - - @Deprecated - public int getInteger(String key, int defaultValue) { - return hasKey(key) ? Integer.parseInt(getString(key)) : defaultValue; - } - - public long getLong(ConfigKey key) { - return getLong(key.getKey()); - } - - @Deprecated - public long getLong(String key) { - return getLong(key, 0); - } - - public long getLong(ConfigKey key, long defaultValue) { - return getLong(key.getKey(), defaultValue); - } - - @Deprecated - public long getLong(String key, long defaultValue) { - return hasKey(key) ? Long.parseLong(getString(key)) : defaultValue; - } - - public double getDouble(ConfigKey key) { - return getDouble(key.getKey()); - } - - @Deprecated - public double getDouble(String key) { - return getDouble(key, 0.0); - } - - public double getDouble(ConfigKey key, double defaultValue) { - return getDouble(key.getKey(), defaultValue); - } - - @Deprecated - public double getDouble(String key, double defaultValue) { - return hasKey(key) ? Double.parseDouble(getString(key)) : defaultValue; - } - - public void setString(ConfigKey key, String value) { - setString(key.getKey(), value); - } - - @Deprecated - public void setString(String key, String value) { - properties.put(key, value); - } - - static String getEnvironmentVariableName(String key) { - return key.replaceAll("\\.", "_").replaceAll("(\\p{Lu})", "_$1").toUpperCase(); - } - -} diff --git a/src/org/traccar/config/ConfigKey.java b/src/org/traccar/config/ConfigKey.java deleted file mode 100644 index 2e54ad392..000000000 --- a/src/org/traccar/config/ConfigKey.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.config; - -public class ConfigKey { - - private final String key; - private final Class clazz; - - ConfigKey(String key, Class clazz) { - this.key = key; - this.clazz = clazz; - } - - String getKey() { - return key; - } - - Class getValueClass() { - return clazz; - } - -} diff --git a/src/org/traccar/config/ConfigSuffix.java b/src/org/traccar/config/ConfigSuffix.java deleted file mode 100644 index 149b2cd00..000000000 --- a/src/org/traccar/config/ConfigSuffix.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.config; - -public class ConfigSuffix extends ConfigKey { - - ConfigSuffix(String key, Class clazz) { - super(key, clazz); - } - - public ConfigKey withPrefix(String prefix) { - return new ConfigKey(prefix + getKey(), getValueClass()); - } - -} diff --git a/src/org/traccar/config/Keys.java b/src/org/traccar/config/Keys.java deleted file mode 100644 index 48cf3e558..000000000 --- a/src/org/traccar/config/Keys.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.config; - -public final class Keys { - - /** - * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old - * connections stay in open state. On most systems there is a limit on number of open connection, so this leads to - * problems with establishing new connections when number of devices is high or devices data connections are - * unstable. - */ - public static final ConfigSuffix PROTOCOL_TIMEOUT = new ConfigSuffix( - ".timeout", Integer.class); - - /** - * Server wide connection timeout value in seconds. See protocol timeout for more information. - */ - public static final ConfigKey SERVER_TIMEOUT = new ConfigKey( - "server.timeout", Integer.class); - - /** - * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the - * statistics screen in the web app. It does not include any sensitive (e.g. locations). - */ - public static final ConfigKey SERVER_STATISTICS = new ConfigKey( - "server.statistics", Boolean.class); - - /** - * Enable events subsystem. Flag to enable all events handlers. - */ - public static final ConfigKey EVENT_ENABLE = new ConfigKey( - "event.enable", Boolean.class); - - /** - * If true, the event is generated once at the beginning of overspeeding period. - */ - public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new ConfigKey( - "event.overspeed.notRepeat", Boolean.class); - - /** - * Minimal over speed duration to trigger the event. Value in seconds. - */ - public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new ConfigKey( - "event.overspeed.minimalDuration", Long.class); - - /** - * Relevant only for geofence speed limits. Use lowest speed limits from all geofences. - */ - public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new ConfigKey( - "event.overspeed.preferLowest", Boolean.class); - - /** - * Do not generate alert event if same alert was present in last known location. - */ - public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new ConfigKey( - "event.ignoreDuplicateAlerts", Boolean.class); - - /** - * List of external handler classes to use in Netty pipeline. - */ - public static final ConfigKey EXTRA_HANDLERS = new ConfigKey( - "extra.handlers", String.class); - - /** - * Enable positions forwarding to other web server. - */ - public static final ConfigKey FORWARD_ENABLE = new ConfigKey( - "forward.enable", Boolean.class); - - /** - * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, - * {latitude} and {longitude} for coordinates. - */ - public static final ConfigKey FORWARD_URL = new ConfigKey( - "forward.url", String.class); - - /** - * Additional HTTP header, can be used for authorization. - */ - public static final ConfigKey FORWARD_HEADER = new ConfigKey( - "forward.header", String.class); - - /** - * Boolean value to enable forwarding in JSON format. - */ - public static final ConfigKey FORWARD_JSON = new ConfigKey( - "forward.json", Boolean.class); - - /** - * Boolean flag to enable or disable position filtering. - */ - public static final ConfigKey FILTER_ENABLE = new ConfigKey( - "filter.enable", Boolean.class); - - /** - * Filter invalid (valid field is set to false) positions. - */ - public static final ConfigKey FILTER_INVALID = new ConfigKey( - "filter.invalid", Boolean.class); - - /** - * Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it usually - * indicates invalid GPS data. - */ - public static final ConfigKey FILTER_ZERO = new ConfigKey( - "filter.zero", Boolean.class); - - /** - * Filter duplicate records (duplicates are detected by time value). - */ - public static final ConfigKey FILTER_DUPLICATE = new ConfigKey( - "filter.duplicate", Boolean.class); - - /** - * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than - * specified number of seconds later than current server time would be filtered out. - */ - public static final ConfigKey FILTER_FUTURE = new ConfigKey( - "filter.future", Long.class); - - /** - * Filter positions with accuracy less than specified value in meters. - */ - public static final ConfigKey FILTER_ACCURACY = new ConfigKey( - "filter.accuracy", Integer.class); - - /** - * Filter cell and wifi locations that are coming from geolocation provider. - */ - public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey( - "filter.approximate", Boolean.class); - - /** - * Filter positions with exactly zero speed values. - */ - public static final ConfigKey FILTER_STATIC = new ConfigKey( - "filter.static", Boolean.class); - - /** - * Filter records by distance. The values is specified in meters. If the new position is less far than this value - * from the last one it gets filtered out. - */ - public static final ConfigKey FILTER_DISTANCE = new ConfigKey( - "filter.distance", Integer.class); - - /** - * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if they're - * marked as valid. Shouldn't be too low. Start testing with values at about 25000. - */ - public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey( - "filter.maxSpeed", Integer.class); - - /** - * Filter position if time from previous position is less than specified value in seconds. - */ - public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey( - "filter.minPeriod", Integer.class); - - /** - * Time limit for the filtering in seconds. If the time difference between last position and a new one is more than - * this limit, the new position will not be filtered out. - */ - public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey( - "filter.skipLimit", Long.class); - - /** - * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. - */ - public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey( - "filter.skipAttributes.enable", Boolean.class); - - /** - * Replaces coordinates with last known if change is less than a 'coordinates.error' meters. Helps to avoid - * coordinates jumps during parking period. - */ - public static final ConfigKey COORDINATES_FILTER = new ConfigKey( - "coordinates.filter", Boolean.class); - - /** - * Distance in meters. Distances below this value gets handled like explained in 'coordinates.filter'. - */ - public static final ConfigKey COORDINATES_MIN_ERROR = new ConfigKey( - "coordinates.minError", Integer.class); - - /** - * Distance in meters. Distances above this value gets handled like explained in 'coordinates.filter', but only if - * Position is also marked as 'invalid'. - */ - public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey( - "filter.maxError", Integer.class); - - /** - * Enable to save device IP addresses information. Disabled by default. - */ - public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new ConfigKey( - "processing.remoteAddress.enable", Boolean.class); - - /** - * Enable engine hours calculation on the server side. It uses ignition value to determine engine state. - */ - public static final ConfigKey PROCESSING_ENGINE_HOURS_ENABLE = new ConfigKey( - "processing.engineHours.enable", Boolean.class); - - /** - * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't - * send some values in every message. - */ - public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new ConfigKey( - "processing.copyAttributes.enable", Boolean.class); - - /** - * Enable computed attributes processing. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ENABLE = new ConfigKey( - "processing.computedAttributes.enable", Boolean.class); - - /** - * Enable computed attributes processing. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new ConfigKey( - "processing.computedAttributes.deviceAttributes", Boolean.class); - - /** - * Boolean flag to enable or disable reverse geocoder. - */ - public static final ConfigKey GEOCODER_ENABLE = new ConfigKey( - "geocoder.enable", Boolean.class); - - /** - * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not - * specified) server uses Google API. - */ - public static final ConfigKey GEOCODER_TYPE = new ConfigKey( - "geocoder.type", String.class); - - /** - * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. - */ - public static final ConfigKey GEOCODER_URL = new ConfigKey( - "geocoder.url", String.class); - - /** - * App id for use with Here provider. - */ - public static final ConfigKey GEOCODER_ID = new ConfigKey( - "geocoder.id", String.class); - - /** - * Provider API key. Most providers require API keys. - */ - public static final ConfigKey GEOCODER_KEY = new ConfigKey( - "geocoder.key", String.class); - - /** - * Language parameter for providers that support localization (e.g. Google and Nominatim). - */ - public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey( - "geocoder.language", String.class); - - /** - * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. - */ - public static final ConfigKey GEOCODER_FORMAT = new ConfigKey( - "geocoder.format", String.class); - - /** - * Cache size for geocoding results. - */ - public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey( - "geocoder.cacheSize", Integer.class); - - /** - * Disable automatic reverse geocoding requests for all positions. - */ - public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey( - "geocoder.ignorePositions", Boolean.class); - - /** - * Boolean flag to apply reverse geocoding to invalid positions. - */ - public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey( - "geocoder.processInvalidPositions", Boolean.class); - - /** - * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than - * specified value (in meters), then Traccar will reuse last known address. - */ - public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey( - "geocoder.reuseDistance", Integer.class); - - /** - * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS - * location is not available. Traccar can determine coordinates based on that information using third party - * services. Default value is false. - */ - public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey( - "geolocation.enable", Boolean.class); - - /** - * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is - * used. You have to supply a key that you get from corresponding provider. For more information see LBS geolocation - * documentation. - */ - public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey( - "geolocation.type", String.class); - - /** - * Geolocation provider API URL address. Not required for most providers. - */ - public static final ConfigKey GEOLOCATION_URL = new ConfigKey( - "geolocation.url", String.class); - - /** - * Provider API key. OpenCellID service requires API key. - */ - public static final ConfigKey GEOLOCATION_KEY = new ConfigKey( - "geolocation.key", String.class); - - /** - * Boolean flag to apply geolocation to invalid positions. - */ - public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey( - "geolocation.processInvalidPositions", Boolean.class); - - /** - * Override latitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can be - * N for North or S for South. - */ - public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new ConfigKey( - "location.latitudeHemisphere", Boolean.class); - - /** - * Override longitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can - * be E for East or W for West. - */ - public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new ConfigKey( - "location.longitudeHemisphere", Boolean.class); - - private Keys() { - } - -} diff --git a/src/org/traccar/database/ActiveDevice.java b/src/org/traccar/database/ActiveDevice.java deleted file mode 100644 index 207fc454b..000000000 --- a/src/org/traccar/database/ActiveDevice.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.Channel; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.net.SocketAddress; - -public class ActiveDevice { - - private final long deviceId; - private final Protocol protocol; - private final Channel channel; - private final SocketAddress remoteAddress; - - public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - this.deviceId = deviceId; - this.protocol = protocol; - this.channel = channel; - this.remoteAddress = remoteAddress; - } - - public Channel getChannel() { - return channel; - } - - public long getDeviceId() { - return deviceId; - } - - public void sendCommand(Command command) { - protocol.sendDataCommand(this, command); - } - - public void write(Object message) { - channel.writeAndFlush(new NetworkMessage(message, remoteAddress)); - } - -} diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java deleted file mode 100644 index 28816645a..000000000 --- a/src/org/traccar/database/AttributesManager.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.Attribute; - -public class AttributesManager extends ExtendedObjectManager<Attribute> { - - public AttributesManager(DataManager dataManager) { - super(dataManager, Attribute.class); - } - - @Override - public void updateCachedItem(Attribute attribute) { - Attribute cachedAttribute = getById(attribute.getId()); - cachedAttribute.setDescription(attribute.getDescription()); - cachedAttribute.setAttribute(attribute.getAttribute()); - cachedAttribute.setExpression(attribute.getExpression()); - cachedAttribute.setType(attribute.getType()); - } - -} diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java deleted file mode 100644 index 8bf9ef860..000000000 --- a/src/org/traccar/database/BaseObjectManager.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.BaseModel; - -public class BaseObjectManager<T extends BaseModel> { - - private static final Logger LOGGER = LoggerFactory.getLogger(BaseObjectManager.class); - - private final DataManager dataManager; - - private Map<Long, T> items; - private Class<T> baseClass; - - protected BaseObjectManager(DataManager dataManager, Class<T> baseClass) { - this.dataManager = dataManager; - this.baseClass = baseClass; - refreshItems(); - } - - protected final DataManager getDataManager() { - return dataManager; - } - - protected final Class<T> getBaseClass() { - return baseClass; - } - - public T getById(long itemId) { - return items.get(itemId); - } - - public void refreshItems() { - if (dataManager != null) { - try { - Collection<T> databaseItems = dataManager.getObjects(baseClass); - if (items == null) { - items = new ConcurrentHashMap<>(databaseItems.size()); - } - Set<Long> databaseItemIds = new HashSet<>(); - for (T item : databaseItems) { - databaseItemIds.add(item.getId()); - if (items.containsKey(item.getId())) { - updateCachedItem(item); - } else { - addNewItem(item); - } - } - for (Long cachedItemId : items.keySet()) { - if (!databaseItemIds.contains(cachedItemId)) { - removeCachedItem(cachedItemId); - } - } - } catch (SQLException error) { - LOGGER.warn("Error refreshing items", error); - } - } - } - - protected void addNewItem(T item) { - items.put(item.getId(), item); - } - - public void addItem(T item) throws SQLException { - dataManager.addObject(item); - addNewItem(item); - } - - protected void updateCachedItem(T item) { - items.put(item.getId(), item); - } - - public void updateItem(T item) throws SQLException { - dataManager.updateObject(item); - updateCachedItem(item); - } - - protected void removeCachedItem(long itemId) { - items.remove(itemId); - } - - public void removeItem(long itemId) throws SQLException { - BaseModel item = getById(itemId); - if (item != null) { - dataManager.removeObject(baseClass, itemId); - removeCachedItem(itemId); - } - } - - public final Collection<T> getItems(Set<Long> itemIds) { - Collection<T> result = new LinkedList<>(); - for (long itemId : itemIds) { - result.add(getById(itemId)); - } - return result; - } - - public Set<Long> getAllItems() { - return items.keySet(); - } - -} diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java deleted file mode 100644 index 44ced1082..000000000 --- a/src/org/traccar/database/CalendarManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.Calendar; - -public class CalendarManager extends SimpleObjectManager<Calendar> { - - public CalendarManager(DataManager dataManager) { - super(dataManager, Calendar.class); - } - -} diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java deleted file mode 100644 index d6fdd66ca..000000000 --- a/src/org/traccar/database/CommandsManager.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocol; -import org.traccar.Context; -import org.traccar.model.Command; -import org.traccar.model.Typed; -import org.traccar.model.Position; - -public class CommandsManager extends ExtendedObjectManager<Command> { - - private static final Logger LOGGER = LoggerFactory.getLogger(CommandsManager.class); - - private final Map<Long, Queue<Command>> deviceQueues = new ConcurrentHashMap<>(); - - private boolean queueing; - - public CommandsManager(DataManager dataManager, boolean queueing) { - super(dataManager, Command.class); - this.queueing = queueing; - } - - public boolean checkDeviceCommand(long deviceId, long commandId) { - return !getAllDeviceItems(deviceId).contains(commandId); - } - - public boolean sendCommand(Command command) throws Exception { - long deviceId = command.getDeviceId(); - if (command.getId() != 0) { - command = getById(command.getId()).clone(); - command.setDeviceId(deviceId); - } - if (command.getTextChannel()) { - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - String phone = Context.getIdentityManager().getById(deviceId).getPhone(); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(phone, command); - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - if (Context.getSmsManager() != null) { - Context.getSmsManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); - } else { - throw new RuntimeException("SMS is not enabled"); - } - } else { - throw new RuntimeException("Command " + command.getType() + " is not supported"); - } - } else { - 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; - } - } - return true; - } - - public Collection<Long> getSupportedCommands(long deviceId) { - List<Long> result = new ArrayList<>(); - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - for (long commandId : getAllDeviceItems(deviceId)) { - Command command = getById(commandId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType()) - || !command.getTextChannel() - && protocol.getSupportedDataCommands().contains(command.getType())) { - result.add(commandId); - } - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - result.add(commandId); - } - } - return result; - } - - public Collection<Typed> getCommandTypes(long deviceId, boolean textChannel) { - List<Typed> result = new ArrayList<>(); - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - Collection<String> commands; - commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); - for (String commandKey : commands) { - result.add(new Typed(commandKey)); - } - } else { - result.add(new Typed(Command.TYPE_CUSTOM)); - } - return result; - } - - public Collection<Typed> getAllCommandTypes() { - List<Typed> result = new ArrayList<>(); - Field[] fields = Command.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - result.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get command types error", error); - } - } - } - return result; - } - - private Queue<Command> getDeviceQueue(long deviceId) { - if (!deviceQueues.containsKey(deviceId)) { - deviceQueues.put(deviceId, new ConcurrentLinkedQueue<Command>()); - } - return deviceQueues.get(deviceId); - } - - public void sendQueuedCommands(ActiveDevice activeDevice) { - Queue<Command> deviceQueue = deviceQueues.get(activeDevice.getDeviceId()); - if (deviceQueue != null) { - Command command = deviceQueue.poll(); - while (command != null) { - activeDevice.sendCommand(command); - command = deviceQueue.poll(); - } - } - } - -} diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java deleted file mode 100644 index 8bae1ea93..000000000 --- a/src/org/traccar/database/ConnectionManager.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.Channel; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.GlobalTimer; -import org.traccar.Main; -import org.traccar.Protocol; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.model.Device; -import org.traccar.model.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.sql.SQLException; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -public class ConnectionManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); - - private static final long DEFAULT_TIMEOUT = 600; - - private final long deviceTimeout; - private final boolean enableStatusEvents; - private final boolean updateDeviceState; - - private final Map<Long, ActiveDevice> activeDevices = new ConcurrentHashMap<>(); - private final Map<Long, Set<UpdateListener>> listeners = new ConcurrentHashMap<>(); - private final Map<Long, Timeout> timeouts = new ConcurrentHashMap<>(); - - public ConnectionManager() { - deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; - enableStatusEvents = Context.getConfig().getBoolean("event.enable"); - updateDeviceState = Context.getConfig().getBoolean("status.updateDeviceState"); - } - - public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); - } - - public void removeActiveDevice(Channel channel) { - for (ActiveDevice activeDevice : activeDevices.values()) { - if (activeDevice.getChannel() == channel) { - updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); - activeDevices.remove(activeDevice.getDeviceId()); - break; - } - } - } - - public ActiveDevice getActiveDevice(long deviceId) { - return activeDevices.get(deviceId); - } - - public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device == null) { - return; - } - - String oldStatus = device.getStatus(); - device.setStatus(status); - - if (enableStatusEvents && !status.equals(oldStatus)) { - String eventType; - Map<Event, Position> events = new HashMap<>(); - switch (status) { - case Device.STATUS_ONLINE: - eventType = Event.TYPE_DEVICE_ONLINE; - break; - case Device.STATUS_UNKNOWN: - eventType = Event.TYPE_DEVICE_UNKNOWN; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - default: - eventType = Event.TYPE_DEVICE_OFFLINE; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - } - events.put(new Event(eventType, deviceId), null); - Context.getNotificationManager().updateEvents(events); - } - - Timeout timeout = timeouts.remove(deviceId); - if (timeout != null) { - timeout.cancel(); - } - - if (time != null) { - device.setLastUpdate(time); - } - - if (status.equals(Device.STATUS_ONLINE)) { - timeouts.put(deviceId, GlobalTimer.getTimer().newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) { - if (!timeout.isCancelled()) { - updateDevice(deviceId, Device.STATUS_UNKNOWN, null); - } - } - }, deviceTimeout, TimeUnit.MILLISECONDS)); - } - - try { - Context.getDeviceManager().updateDeviceStatus(device); - } catch (SQLException error) { - LOGGER.warn("Update device status error", error); - } - - 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) { - DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - Map<Event, Position> result = new HashMap<>(); - - Map<Event, Position> event = Main.getInjector() - .getInstance(MotionEventHandler.class).updateMotionState(deviceState); - if (event != null) { - result.putAll(event); - } - - event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false)); - if (event != null) { - result.putAll(event); - } - - return result; - } - - public synchronized void updateDevice(Device device) { - for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateDevice(device); - } - } - } - } - - public synchronized void updatePosition(Position position) { - long deviceId = position.getDeviceId(); - - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdatePosition(position); - } - } - } - } - - public synchronized void updateEvent(long userId, Event event) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateEvent(event); - } - } - } - - public interface UpdateListener { - void onUpdateDevice(Device device); - void onUpdatePosition(Position position); - void onUpdateEvent(Event event); - } - - public synchronized void addListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<UpdateListener>()); - } - listeners.get(userId).add(listener); - } - - public synchronized void removeListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<UpdateListener>()); - } - listeners.get(userId).remove(listener); - } - -} diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java deleted file mode 100644 index 8e9071736..000000000 --- a/src/org/traccar/database/DataManager.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 java.beans.Introspector; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import javax.naming.InitialContext; -import javax.sql.DataSource; - -import liquibase.Contexts; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; -import liquibase.resource.ResourceAccessor; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.Context; -import org.traccar.helper.DateUtil; -import org.traccar.model.Attribute; -import org.traccar.model.Device; -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; -import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; -import org.traccar.model.Command; -import org.traccar.model.Position; -import org.traccar.model.Server; -import org.traccar.model.Statistics; -import org.traccar.model.User; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; - -public class DataManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(DataManager.class); - - public static final String ACTION_SELECT_ALL = "selectAll"; - public static final String ACTION_SELECT = "select"; - public static final String ACTION_INSERT = "insert"; - public static final String ACTION_UPDATE = "update"; - public static final String ACTION_DELETE = "delete"; - - private final Config config; - - private DataSource dataSource; - - private boolean generateQueries; - - private boolean forceLdap; - - public DataManager(Config config) throws Exception { - this.config = config; - - forceLdap = config.getBoolean("ldap.force"); - - initDatabase(); - initDatabaseSchema(); - } - - private void initDatabase() throws Exception { - - String jndiName = config.getString("database.jndi"); - - if (jndiName != null) { - - dataSource = (DataSource) new InitialContext().lookup(jndiName); - - } else { - - String driverFile = config.getString("database.driverFile"); - if (driverFile != null) { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - try { - Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(classLoader, new File(driverFile).toURI().toURL()); - } catch (NoSuchMethodException e) { - Method method = classLoader.getClass() - .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); - method.setAccessible(true); - method.invoke(classLoader, driverFile); - } - } - - String driver = config.getString("database.driver"); - if (driver != null) { - Class.forName(driver); - } - - HikariConfig hikariConfig = new HikariConfig(); - hikariConfig.setDriverClassName(config.getString("database.driver")); - hikariConfig.setJdbcUrl(config.getString("database.url")); - hikariConfig.setUsername(config.getString("database.user")); - hikariConfig.setPassword(config.getString("database.password")); - hikariConfig.setConnectionInitSql(config.getString("database.checkConnection", "SELECT 1")); - hikariConfig.setIdleTimeout(600000); - - int maxPoolSize = config.getInteger("database.maxPoolSize"); - - if (maxPoolSize != 0) { - hikariConfig.setMaximumPoolSize(maxPoolSize); - } - - generateQueries = config.getBoolean("database.generateQueries"); - - dataSource = new HikariDataSource(hikariConfig); - - } - } - - public static String constructObjectQuery(String action, Class<?> clazz, boolean extended) { - switch (action) { - case ACTION_INSERT: - case ACTION_UPDATE: - StringBuilder result = new StringBuilder(); - StringBuilder fields = new StringBuilder(); - StringBuilder values = new StringBuilder(); - - Set<Method> methods = new HashSet<>(Arrays.asList(clazz.getMethods())); - methods.removeAll(Arrays.asList(Object.class.getMethods())); - methods.removeAll(Arrays.asList(BaseModel.class.getMethods())); - for (Method method : methods) { - boolean skip; - if (extended) { - skip = !method.isAnnotationPresent(QueryExtended.class); - } else { - skip = method.isAnnotationPresent(QueryIgnore.class) - || method.isAnnotationPresent(QueryExtended.class) && !action.equals(ACTION_INSERT); - } - if (!skip && method.getName().startsWith("get") && method.getParameterTypes().length == 0) { - String name = Introspector.decapitalize(method.getName().substring(3)); - if (action.equals(ACTION_INSERT)) { - fields.append(name).append(", "); - values.append(":").append(name).append(", "); - } else { - fields.append(name).append(" = :").append(name).append(", "); - } - } - } - fields.setLength(fields.length() - 2); - if (action.equals(ACTION_INSERT)) { - values.setLength(values.length() - 2); - result.append("INSERT INTO ").append(getObjectsTableName(clazz)).append(" ("); - result.append(fields).append(") "); - result.append("VALUES (").append(values).append(")"); - } else { - result.append("UPDATE ").append(getObjectsTableName(clazz)).append(" SET "); - result.append(fields); - result.append(" WHERE id = :id"); - } - return result.toString(); - case ACTION_SELECT_ALL: - return "SELECT * FROM " + getObjectsTableName(clazz); - case ACTION_SELECT: - return "SELECT * FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; - case ACTION_DELETE: - return "DELETE FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; - default: - throw new IllegalArgumentException("Unknown action"); - } - } - - 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"); - } - } - - private String getQuery(String key) { - String query = config.getString(key); - if (query == null) { - LOGGER.info("Query not provided: " + key); - } - return query; - } - - public String getQuery(String action, Class<?> clazz) { - return getQuery(action, clazz, false); - } - - public String getQuery(String action, Class<?> clazz, boolean extended) { - String queryName; - if (action.equals(ACTION_SELECT_ALL)) { - queryName = "database.select" + clazz.getSimpleName() + "s"; - } else { - queryName = "database." + action.toLowerCase() + clazz.getSimpleName(); - if (extended) { - queryName += "Extended"; - } - } - String query = config.getString(queryName); - if (query == null) { - if (generateQueries) { - query = constructObjectQuery(action, clazz, extended); - config.setString(queryName, query); - } else { - LOGGER.info("Query not provided: " + queryName); - } - } - - return query; - } - - public String getQuery(String action, Class<?> owner, Class<?> property) { - String queryName; - switch (action) { - case ACTION_SELECT_ALL: - queryName = "database.select" + owner.getSimpleName() + property.getSimpleName() + "s"; - break; - case ACTION_INSERT: - queryName = "database.link" + owner.getSimpleName() + property.getSimpleName(); - break; - default: - queryName = "database.unlink" + owner.getSimpleName() + property.getSimpleName(); - break; - } - String query = config.getString(queryName); - if (query == null) { - if (generateQueries) { - query = constructPermissionQuery(action, owner, - property.equals(User.class) ? ManagedUser.class : property); - config.setString(queryName, query); - } else { - LOGGER.info("Query not provided: " + queryName); - } - } - - return query; - } - - private static String getPermissionsTableName(Class<?> owner, Class<?> property) { - String propertyName = property.getSimpleName(); - if (propertyName.equals("ManagedUser")) { - propertyName = "User"; - } - return "tc_" + Introspector.decapitalize(owner.getSimpleName()) - + "_" + Introspector.decapitalize(propertyName); - } - - private static String getObjectsTableName(Class<?> clazz) { - String result = "tc_" + Introspector.decapitalize(clazz.getSimpleName()); - // Add "s" ending if object name is not plural already - if (!result.endsWith("s")) { - result += "s"; - } - return result; - } - - private void initDatabaseSchema() throws SQLException, LiquibaseException { - - if (config.hasKey("database.changelog")) { - - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(); - - Database database = DatabaseFactory.getInstance().openDatabase( - config.getString("database.url"), - config.getString("database.user"), - config.getString("database.password"), - config.getString("database.driver"), - null, null, null, resourceAccessor); - - Liquibase liquibase = new Liquibase( - config.getString("database.changelog"), resourceAccessor, database); - - liquibase.clearCheckSums(); - - liquibase.update(new Contexts()); - } - } - - public User login(String email, String password) throws SQLException { - User user = QueryBuilder.create(dataSource, getQuery("database.loginUser")) - .setString("email", email.trim()) - .executeQuerySingle(User.class); - LdapProvider ldapProvider = Context.getLdapProvider(); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - Context.getUsersManager().addItem(user); - return user; - } - } - return null; - } - - public void updateDeviceStatus(Device device) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, Device.class, true)) - .setObject(device) - .executeUpdate(); - } - - public Collection<Position> getPositions(long deviceId, Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectPositions")) - .setLong("deviceId", deviceId) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Position.class); - } - - public void updateLatestPosition(Position position) throws SQLException { - QueryBuilder.create(dataSource, getQuery("database.updateLatestPosition")) - .setDate("now", new Date()) - .setObject(position) - .executeUpdate(); - } - - public Collection<Position> getLatestPositions() throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectLatestPositions")) - .executeQuery(Position.class); - } - - public void clearHistory() throws SQLException { - long historyDays = config.getInteger("database.historyDays"); - if (historyDays != 0) { - Date timeLimit = new Date(System.currentTimeMillis() - historyDays * 24 * 3600 * 1000); - LOGGER.info("Clearing history earlier than " + DateUtil.formatDate(timeLimit, false)); - QueryBuilder.create(dataSource, getQuery("database.deletePositions")) - .setDate("serverTime", timeLimit) - .executeUpdate(); - QueryBuilder.create(dataSource, getQuery("database.deleteEvents")) - .setDate("serverTime", timeLimit) - .executeUpdate(); - } - } - - public Server getServer() throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, Server.class)) - .executeQuerySingle(Server.class); - } - - public Collection<Event> getEvents(long deviceId, Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectEvents")) - .setLong("deviceId", deviceId) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Event.class); - } - - public Collection<Statistics> getStatistics(Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectStatistics")) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Statistics.class); - } - - public static Class<?> getClassByName(String name) throws ClassNotFoundException { - switch (name.toLowerCase().replace("id", "")) { - case "device": - return Device.class; - case "group": - return Group.class; - case "user": - return User.class; - case "manageduser": - return ManagedUser.class; - case "geofence": - return Geofence.class; - case "driver": - return Driver.class; - case "attribute": - return Attribute.class; - case "calendar": - return Calendar.class; - case "command": - return Command.class; - case "maintenance": - return Maintenance.class; - case "notification": - return Notification.class; - default: - throw new ClassNotFoundException(); - } - } - - private static String makeNameId(Class<?> clazz) { - String name = clazz.getSimpleName(); - return Introspector.decapitalize(name) + (!name.contains("Id") ? "Id" : ""); - } - - public Collection<Permission> getPermissions(Class<? extends BaseModel> owner, Class<? extends BaseModel> property) - throws SQLException, ClassNotFoundException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, owner, property)) - .executePermissionsQuery(); - } - - public void linkObject(Class<?> owner, long ownerId, Class<?> property, long propertyId, boolean link) - throws SQLException { - QueryBuilder.create(dataSource, getQuery(link ? ACTION_INSERT : ACTION_DELETE, owner, property)) - .setLong(makeNameId(owner), ownerId) - .setLong(makeNameId(property), propertyId) - .executeUpdate(); - } - - public <T extends BaseModel> T getObject(Class<T> clazz, long entityId) throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT, clazz)) - .setLong("id", entityId) - .executeQuerySingle(clazz); - } - - public <T extends BaseModel> Collection<T> getObjects(Class<T> clazz) throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, clazz)) - .executeQuery(clazz); - } - - public void addObject(BaseModel entity) throws SQLException { - entity.setId(QueryBuilder.create(dataSource, getQuery(ACTION_INSERT, entity.getClass()), true) - .setObject(entity) - .executeUpdate()); - } - - public void updateObject(BaseModel entity) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, entity.getClass())) - .setObject(entity) - .executeUpdate(); - if (entity instanceof User && ((User) entity).getHashedPassword() != null) { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, User.class, true)) - .setObject(entity) - .executeUpdate(); - } - } - - public void removeObject(Class<? extends BaseModel> clazz, long entityId) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_DELETE, clazz)) - .setLong("id", entityId) - .executeUpdate(); - } - -} diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java deleted file mode 100644 index de4607d1f..000000000 --- a/src/org/traccar/database/DeviceManager.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * 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. - * 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 java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.DeviceState; -import org.traccar.model.DeviceAccumulators; -import org.traccar.model.Group; -import org.traccar.model.Position; -import org.traccar.model.Server; - -public class DeviceManager extends BaseObjectManager<Device> implements IdentityManager, ManagableObjects { - - private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); - - public static final long DEFAULT_REFRESH_DELAY = 300; - - private final Config config; - private final long dataRefreshDelay; - private boolean lookupGroupsAttribute; - - private Map<String, Device> devicesByUniqueId; - private Map<String, Device> devicesByPhone; - private AtomicLong devicesLastUpdate = new AtomicLong(); - - private final Map<Long, Position> positions = new ConcurrentHashMap<>(); - - private final Map<Long, DeviceState> deviceStates = new ConcurrentHashMap<>(); - - public DeviceManager(DataManager dataManager) { - super(dataManager, Device.class); - this.config = Context.getConfig(); - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(); - } - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(); - } - dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; - lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute"); - refreshLastPositions(); - } - - @Override - public long addUnknownDevice(String uniqueId) { - Device device = new Device(); - device.setName(uniqueId); - device.setUniqueId(uniqueId); - device.setCategory(Context.getConfig().getString("database.registerUnknown.defaultCategory")); - - long defaultGroupId = Context.getConfig().getLong("database.registerUnknown.defaultGroupId"); - if (defaultGroupId != 0) { - device.setGroupId(defaultGroupId); - } - - try { - addItem(device); - - LOGGER.info("Automatically registered device " + uniqueId); - - if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - - return device.getId(); - } catch (SQLException e) { - LOGGER.warn("Automatic device registration error", e); - return 0; - } - } - - public void updateDeviceCache(boolean force) throws SQLException { - long lastUpdate = devicesLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) - && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - refreshItems(); - } - } - - @Override - public Device getByUniqueId(String uniqueId) throws SQLException { - boolean forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); - - updateDeviceCache(forceUpdate); - - return devicesByUniqueId.get(uniqueId); - } - - public Device getDeviceByPhone(String phone) { - return devicesByPhone.get(phone); - } - - @Override - public Set<Long> getAllItems() { - Set<Long> result = super.getAllItems(); - if (result.isEmpty()) { - try { - updateDeviceCache(true); - } catch (SQLException e) { - LOGGER.warn("Update device cache error", e); - } - result = super.getAllItems(); - } - return result; - } - - public Collection<Device> getAllDevices() { - return getItems(getAllItems()); - } - - public Set<Long> getAllUserItems(long userId) { - return Context.getPermissionsManager().getDevicePermissions(userId); - } - - @Override - public Set<Long> getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - Set<Long> result = new HashSet<>(); - for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { - Device device = getById(deviceId); - if (device != null && !device.getDisabled()) { - result.add(deviceId); - } - } - return result; - } else { - return new HashSet<>(); - } - } - - public Set<Long> getAllManagedItems(long userId) { - Set<Long> result = new HashSet<>(); - result.addAll(getAllUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getAllUserItems(managedUserId)); - } - return result; - } - - @Override - public Set<Long> getManagedItems(long userId) { - Set<Long> result = new HashSet<>(); - result.addAll(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - - private void putUniqueDeviceId(Device device) { - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); - } - devicesByUniqueId.put(device.getUniqueId(), device); - } - - private void putPhone(Device device) { - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(getAllItems().size()); - } - devicesByPhone.put(device.getPhone(), device); - } - - @Override - protected void addNewItem(Device device) { - super.addNewItem(device); - putUniqueDeviceId(device); - if (device.getPhone() != null && !device.getPhone().isEmpty()) { - putPhone(device); - } - if (Context.getGeofenceManager() != null) { - Position lastPosition = getLastPosition(device.getId()); - if (lastPosition != null) { - device.setGeofenceIds(Context.getGeofenceManager().getCurrentDeviceGeofences(lastPosition)); - } - } - } - - @Override - protected void updateCachedItem(Device device) { - Device cachedDevice = getById(device.getId()); - cachedDevice.setName(device.getName()); - cachedDevice.setGroupId(device.getGroupId()); - cachedDevice.setCategory(device.getCategory()); - cachedDevice.setContact(device.getContact()); - cachedDevice.setModel(device.getModel()); - cachedDevice.setDisabled(device.getDisabled()); - cachedDevice.setAttributes(device.getAttributes()); - if (!device.getUniqueId().equals(cachedDevice.getUniqueId())) { - devicesByUniqueId.remove(cachedDevice.getUniqueId()); - cachedDevice.setUniqueId(device.getUniqueId()); - putUniqueDeviceId(cachedDevice); - } - if (device.getPhone() != null && !device.getPhone().isEmpty() - && !device.getPhone().equals(cachedDevice.getPhone())) { - String phone = cachedDevice.getPhone(); - if (phone != null && !phone.isEmpty()) { - devicesByPhone.remove(phone); - } - cachedDevice.setPhone(device.getPhone()); - putPhone(cachedDevice); - } - } - - @Override - protected void removeCachedItem(long deviceId) { - Device cachedDevice = getById(deviceId); - if (cachedDevice != null) { - String deviceUniqueId = cachedDevice.getUniqueId(); - String phone = cachedDevice.getPhone(); - super.removeCachedItem(deviceId); - devicesByUniqueId.remove(deviceUniqueId); - if (phone != null && !phone.isEmpty()) { - devicesByPhone.remove(phone); - } - } - positions.remove(deviceId); - } - - public void updateDeviceStatus(Device device) throws SQLException { - getDataManager().updateDeviceStatus(device); - Device cachedDevice = getById(device.getId()); - if (cachedDevice != null) { - cachedDevice.setStatus(device.getStatus()); - } - } - - private void refreshLastPositions() { - if (getDataManager() != null) { - try { - for (Position position : getDataManager().getLatestPositions()) { - positions.put(position.getDeviceId(), position); - } - } catch (SQLException error) { - LOGGER.warn("Load latest positions error", error); - } - } - } - - public boolean isLatestPosition(Position position) { - Position lastPosition = getLastPosition(position.getDeviceId()); - return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; - } - - public void updateLatestPosition(Position position) throws SQLException { - - if (isLatestPosition(position)) { - - getDataManager().updateLatestPosition(position); - - Device device = getById(position.getDeviceId()); - if (device != null) { - device.setPositionId(position.getId()); - } - - positions.put(position.getDeviceId(), position); - - if (Context.getConnectionManager() != null) { - Context.getConnectionManager().updatePosition(position); - } - } - } - - @Override - public Position getLastPosition(long deviceId) { - return positions.get(deviceId); - } - - public Collection<Position> getInitialState(long userId) { - - List<Position> result = new LinkedList<>(); - - if (Context.getPermissionsManager() != null) { - for (long deviceId : Context.getPermissionsManager().getUserAdmin(userId) - ? getAllUserItems(userId) : getUserItems(userId)) { - if (positions.containsKey(deviceId)) { - result.add(positions.get(deviceId)); - } - } - } - - return result; - } - - @Override - public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result instanceof String ? Boolean.parseBoolean((String) result) : (Boolean) result; - } - return defaultValue; - } - - @Override - public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? (String) result : defaultValue; - } - - @Override - public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result instanceof String ? Integer.parseInt((String) result) : ((Number) result).intValue(); - } - return defaultValue; - } - - @Override - public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result instanceof String ? Long.parseLong((String) result) : ((Number) result).longValue(); - } - return defaultValue; - } - - public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result instanceof String ? Double.parseDouble((String) result) : ((Number) result).doubleValue(); - } - return defaultValue; - } - - private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { - Object result = null; - Device device = getById(deviceId); - if (device != null) { - result = device.getAttributes().get(attributeName); - if (result == null && lookupGroupsAttribute) { - long groupId = device.getGroupId(); - while (groupId != 0) { - Group group = Context.getGroupsManager().getById(groupId); - if (group != null) { - result = group.getAttributes().get(attributeName); - if (result != null) { - break; - } - groupId = group.getGroupId(); - } else { - groupId = 0; - } - } - } - if (result == null) { - if (lookupConfig) { - result = Context.getConfig().getString(attributeName); - } else { - Server server = Context.getPermissionsManager().getServer(); - result = server.getAttributes().get(attributeName); - } - } - } - return result; - } - - public void resetDeviceAccumulators(DeviceAccumulators deviceAccumulators) throws SQLException { - Position last = positions.get(deviceAccumulators.getDeviceId()); - if (last != null) { - if (deviceAccumulators.getTotalDistance() != null) { - last.getAttributes().put(Position.KEY_TOTAL_DISTANCE, deviceAccumulators.getTotalDistance()); - } - if (deviceAccumulators.getHours() != null) { - last.getAttributes().put(Position.KEY_HOURS, deviceAccumulators.getHours()); - } - getDataManager().addObject(last); - updateLatestPosition(last); - } else { - throw new IllegalArgumentException(); - } - } - - public DeviceState getDeviceState(long deviceId) { - DeviceState deviceState = deviceStates.get(deviceId); - if (deviceState == null) { - deviceState = new DeviceState(); - deviceStates.put(deviceId, deviceState); - } - return deviceState; - } - - public void setDeviceState(long deviceId, DeviceState deviceState) { - deviceStates.put(deviceId, deviceState); - } - -} diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java deleted file mode 100644 index 930951460..000000000 --- a/src/org/traccar/database/DriversManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.Driver; - -public class DriversManager extends ExtendedObjectManager<Driver> { - - private Map<String, Driver> driversByUniqueId; - - public DriversManager(DataManager dataManager) { - super(dataManager, Driver.class); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - } - - private void putUniqueDriverId(Driver driver) { - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); - } - driversByUniqueId.put(driver.getUniqueId(), driver); - } - - @Override - protected void addNewItem(Driver driver) { - super.addNewItem(driver); - putUniqueDriverId(driver); - } - - @Override - protected void updateCachedItem(Driver driver) { - Driver cachedDriver = getById(driver.getId()); - cachedDriver.setName(driver.getName()); - if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { - driversByUniqueId.remove(cachedDriver.getUniqueId()); - cachedDriver.setUniqueId(driver.getUniqueId()); - putUniqueDriverId(cachedDriver); - } - cachedDriver.setAttributes(driver.getAttributes()); - } - - @Override - protected void removeCachedItem(long driverId) { - Driver cachedDriver = getById(driverId); - if (cachedDriver != null) { - String driverUniqueId = cachedDriver.getUniqueId(); - super.removeCachedItem(driverId); - driversByUniqueId.remove(driverUniqueId); - } - } - - public Driver getDriverByUniqueId(String uniqueId) { - return driversByUniqueId.get(uniqueId); - } -} diff --git a/src/org/traccar/database/ExtendedObjectManager.java b/src/org/traccar/database/ExtendedObjectManager.java deleted file mode 100644 index ceb85b537..000000000 --- a/src/org/traccar/database/ExtendedObjectManager.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.BaseModel; - -public abstract class ExtendedObjectManager<T extends BaseModel> extends SimpleObjectManager<T> { - - private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedObjectManager.class); - - private final Map<Long, Set<Long>> deviceItems = new ConcurrentHashMap<>(); - private final Map<Long, Set<Long>> deviceItemsWithGroups = new ConcurrentHashMap<>(); - private final Map<Long, Set<Long>> groupItems = new ConcurrentHashMap<>(); - - protected ExtendedObjectManager(DataManager dataManager, Class<T> baseClass) { - super(dataManager, baseClass); - refreshExtendedPermissions(); - } - - public final Set<Long> getGroupItems(long groupId) { - if (!groupItems.containsKey(groupId)) { - groupItems.put(groupId, new HashSet<Long>()); - } - return groupItems.get(groupId); - } - - public final Set<Long> getDeviceItems(long deviceId) { - if (!deviceItems.containsKey(deviceId)) { - deviceItems.put(deviceId, new HashSet<Long>()); - } - return deviceItems.get(deviceId); - } - - public Set<Long> getAllDeviceItems(long deviceId) { - if (!deviceItemsWithGroups.containsKey(deviceId)) { - deviceItemsWithGroups.put(deviceId, new HashSet<Long>()); - } - return deviceItemsWithGroups.get(deviceId); - } - - @Override - public void removeItem(long itemId) throws SQLException { - super.removeItem(itemId); - refreshExtendedPermissions(); - } - - public void refreshExtendedPermissions() { - if (getDataManager() != null) { - try { - - Collection<Permission> databaseGroupPermissions = - getDataManager().getPermissions(Group.class, getBaseClass()); - - groupItems.clear(); - for (Permission groupPermission : databaseGroupPermissions) { - getGroupItems(groupPermission.getOwnerId()).add(groupPermission.getPropertyId()); - } - - Collection<Permission> databaseDevicePermissions = - getDataManager().getPermissions(Device.class, getBaseClass()); - - deviceItems.clear(); - deviceItemsWithGroups.clear(); - - for (Permission devicePermission : databaseDevicePermissions) { - getDeviceItems(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); - getAllDeviceItems(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); - } - - for (Device device : Context.getDeviceManager().getAllDevices()) { - long groupId = device.getGroupId(); - while (groupId != 0) { - getAllDeviceItems(device.getId()).addAll(getGroupItems(groupId)); - Group group = Context.getGroupsManager().getById(groupId); - if (group != null) { - groupId = group.getGroupId(); - } else { - groupId = 0; - } - } - } - - } catch (SQLException | ClassNotFoundException error) { - LOGGER.warn("Refresh permissions error", error); - } - } - } -} diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java deleted file mode 100644 index a32847cf9..000000000 --- a/src/org/traccar/database/GeofenceManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 java.util.ArrayList; -import java.util.List; - -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Geofence; -import org.traccar.model.Position; - -public class GeofenceManager extends ExtendedObjectManager<Geofence> { - - public GeofenceManager(DataManager dataManager) { - super(dataManager, Geofence.class); - } - - @Override - public final void refreshExtendedPermissions() { - super.refreshExtendedPermissions(); - recalculateDevicesGeofences(); - } - - public List<Long> getCurrentDeviceGeofences(Position position) { - List<Long> result = new ArrayList<>(); - for (long geofenceId : getAllDeviceItems(position.getDeviceId())) { - Geofence geofence = getById(geofenceId); - if (geofence != null && geofence.getGeometry() - .containsPoint(position.getLatitude(), position.getLongitude())) { - result.add(geofenceId); - } - } - return result; - } - - public void recalculateDevicesGeofences() { - for (Device device : Context.getDeviceManager().getAllDevices()) { - List<Long> deviceGeofenceIds = device.getGeofenceIds(); - if (deviceGeofenceIds == null) { - deviceGeofenceIds = new ArrayList<>(); - } else { - deviceGeofenceIds.clear(); - } - Position lastPosition = Context.getIdentityManager().getLastPosition(device.getId()); - if (lastPosition != null && getAllDeviceItems(device.getId()) != null) { - deviceGeofenceIds.addAll(getCurrentDeviceGeofences(lastPosition)); - } - device.setGeofenceIds(deviceGeofenceIds); - } - } - -} diff --git a/src/org/traccar/database/GroupTree.java b/src/org/traccar/database/GroupTree.java deleted file mode 100644 index 8798f55bc..000000000 --- a/src/org/traccar/database/GroupTree.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.Device; -import org.traccar.model.Group; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class GroupTree { - - private static class TreeNode { - - private Group group; - private Device device; - private Collection<TreeNode> children = new HashSet<>(); - - TreeNode(Group group) { - this.group = group; - } - - TreeNode(Device device) { - this.device = device; - } - - @Override - public int hashCode() { - if (group != null) { - return (int) group.getId(); - } else { - return (int) device.getId(); - } - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof TreeNode)) { - return false; - } - TreeNode other = (TreeNode) obj; - if (other == this) { - return true; - } - if (group != null && other.group != null) { - return group.getId() == other.group.getId(); - } else if (device != null && other.device != null) { - return device.getId() == other.device.getId(); - } - return false; - } - - public Group getGroup() { - return group; - } - - public Device getDevice() { - return device; - } - - public void setParent(TreeNode parent) { - if (parent != null) { - parent.children.add(this); - } - } - - public Collection<TreeNode> getChildren() { - return children; - } - - } - - private final Map<Long, TreeNode> groupMap = new HashMap<>(); - - public GroupTree(Collection<Group> groups, Collection<Device> devices) { - - for (Group group : groups) { - groupMap.put(group.getId(), new TreeNode(group)); - } - - for (TreeNode node : groupMap.values()) { - if (node.getGroup().getGroupId() != 0) { - node.setParent(groupMap.get(node.getGroup().getGroupId())); - } - } - - Map<Long, TreeNode> deviceMap = new HashMap<>(); - - for (Device device : devices) { - deviceMap.put(device.getId(), new TreeNode(device)); - } - - for (TreeNode node : deviceMap.values()) { - if (node.getDevice().getGroupId() != 0) { - node.setParent(groupMap.get(node.getDevice().getGroupId())); - } - } - - } - - public Collection<Group> getGroups(long groupId) { - Set<TreeNode> results = new HashSet<>(); - getNodes(results, groupMap.get(groupId)); - Collection<Group> groups = new ArrayList<>(); - for (TreeNode node : results) { - if (node.getGroup() != null) { - groups.add(node.getGroup()); - } - } - return groups; - } - - public Collection<Device> getDevices(long groupId) { - Set<TreeNode> results = new HashSet<>(); - getNodes(results, groupMap.get(groupId)); - Collection<Device> devices = new ArrayList<>(); - for (TreeNode node : results) { - if (node.getDevice() != null) { - devices.add(node.getDevice()); - } - } - return devices; - } - - private void getNodes(Set<TreeNode> results, TreeNode node) { - if (node != null) { - for (TreeNode child : node.getChildren()) { - results.add(child); - getNodes(results, child); - } - } - } - -} diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java deleted file mode 100644 index d8404c614..000000000 --- a/src/org/traccar/database/GroupsManager.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.sql.SQLException; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Group; - -public class GroupsManager extends BaseObjectManager<Group> implements ManagableObjects { - - private static final Logger LOGGER = LoggerFactory.getLogger(GroupsManager.class); - - private AtomicLong groupsLastUpdate = new AtomicLong(); - private final long dataRefreshDelay; - - public GroupsManager(DataManager dataManager) { - super(dataManager, Group.class); - dataRefreshDelay = Context.getConfig().getLong("database.refreshDelay", - DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; - } - - private void checkGroupCycles(Group group) { - Set<Long> groups = new HashSet<>(); - while (group != null) { - if (groups.contains(group.getId())) { - throw new IllegalArgumentException("Cycle in group hierarchy"); - } - groups.add(group.getId()); - group = getById(group.getGroupId()); - } - } - - public void updateGroupCache(boolean force) throws SQLException { - long lastUpdate = groupsLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) - && groupsLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - refreshItems(); - } - } - - @Override - public Set<Long> getAllItems() { - Set<Long> result = super.getAllItems(); - if (result.isEmpty()) { - try { - updateGroupCache(true); - } catch (SQLException e) { - LOGGER.warn("Update group cache error", e); - } - result = super.getAllItems(); - } - return result; - } - - @Override - protected void addNewItem(Group group) { - checkGroupCycles(group); - super.addNewItem(group); - } - - @Override - public void updateItem(Group group) throws SQLException { - checkGroupCycles(group); - super.updateItem(group); - } - - @Override - public Set<Long> getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - return Context.getPermissionsManager().getGroupPermissions(userId); - } else { - return new HashSet<>(); - } - } - - @Override - public Set<Long> getManagedItems(long userId) { - Set<Long> result = new HashSet<>(); - result.addAll(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - -} diff --git a/src/org/traccar/database/IdentityManager.java b/src/org/traccar/database/IdentityManager.java deleted file mode 100644 index 6228a0f75..000000000 --- a/src/org/traccar/database/IdentityManager.java +++ /dev/null @@ -1,43 +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.database; - -import org.traccar.model.Device; -import org.traccar.model.Position; - -public interface IdentityManager { - - long addUnknownDevice(String uniqueId); - - Device getById(long id); - - Device getByUniqueId(String uniqueId) throws Exception; - - Position getLastPosition(long deviceId); - - boolean isLatestPosition(Position position); - - boolean lookupAttributeBoolean(long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig); - - String lookupAttributeString(long deviceId, String attributeName, String defaultValue, boolean lookupConfig); - - int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig); - - long lookupAttributeLong(long deviceId, String attributeName, long defaultValue, boolean lookupConfig); - - double lookupAttributeDouble(long deviceId, String attributeName, double defaultValue, boolean lookupConfig); - -} diff --git a/src/org/traccar/database/LdapProvider.java b/src/org/traccar/database/LdapProvider.java deleted file mode 100644 index d8b5c9f52..000000000 --- a/src/org/traccar/database/LdapProvider.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.database; - -import javax.naming.Context; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.InitialDirContext; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.model.User; - -import java.util.Hashtable; - -public class LdapProvider { - - private static final Logger LOGGER = LoggerFactory.getLogger(LdapProvider.class); - - private String url; - private String searchBase; - private String idAttribute; - private String nameAttribute; - private String mailAttribute; - private String searchFilter; - private String adminFilter; - private String serviceUser; - private String servicePassword; - - public LdapProvider(Config config) { - String url = config.getString("ldap.url"); - if (url != null) { - this.url = url; - } else { - this.url = "ldap://" + config.getString("ldap.server") + ":" + config.getInteger("ldap.port", 389); - } - this.searchBase = config.getString("ldap.base"); - this.idAttribute = config.getString("ldap.idAttribute", "uid"); - this.nameAttribute = config.getString("ldap.nameAttribute", "cn"); - this.mailAttribute = config.getString("ldap.mailAttribute", "mail"); - this.searchFilter = config.getString("ldap.searchFilter", "(" + idAttribute + "=:login)"); - String adminGroup = config.getString("ldap.adminGroup"); - this.adminFilter = config.getString("ldap.adminFilter"); - if (this.adminFilter == null && adminGroup != null) { - this.adminFilter = "(&(" + idAttribute + "=:login)(memberOf=" + adminGroup + "))"; - } - this.serviceUser = config.getString("ldap.user"); - this.servicePassword = config.getString("ldap.password"); - } - - private InitialDirContext auth(String accountName, String password) throws NamingException { - Hashtable<String, String> env = new Hashtable<>(); - env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); - env.put(Context.PROVIDER_URL, url); - - env.put(Context.SECURITY_AUTHENTICATION, "simple"); - env.put(Context.SECURITY_PRINCIPAL, accountName); - env.put(Context.SECURITY_CREDENTIALS, password); - - return new InitialDirContext(env); - } - - private boolean isAdmin(String accountName) { - if (this.adminFilter != null) { - try { - InitialDirContext context = initContext(); - String searchString = adminFilter.replace(":login", accountName); - SearchControls searchControls = new SearchControls(); - searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); - NamingEnumeration<SearchResult> results = context.search(searchBase, searchString, searchControls); - if (results.hasMoreElements()) { - results.nextElement(); - if (results.hasMoreElements()) { - LOGGER.warn("Matched multiple users for the accountName: " + accountName); - return false; - } - return true; - } - } catch (NamingException e) { - return false; - } - } - return false; - } - - public InitialDirContext initContext() throws NamingException { - return auth(serviceUser, servicePassword); - } - - private SearchResult lookupUser(String accountName) throws NamingException { - InitialDirContext context = initContext(); - - String searchString = searchFilter.replace(":login", accountName); - - SearchControls searchControls = new SearchControls(); - String[] attributeFilter = {idAttribute, nameAttribute, mailAttribute}; - searchControls.setReturningAttributes(attributeFilter); - searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); - - NamingEnumeration<SearchResult> results = context.search(searchBase, searchString, searchControls); - - SearchResult searchResult = null; - if (results.hasMoreElements()) { - searchResult = results.nextElement(); - if (results.hasMoreElements()) { - LOGGER.warn("Matched multiple users for the accountName: " + accountName); - return null; - } - } - - return searchResult; - } - - public User getUser(String accountName) { - SearchResult ldapUser; - User user = new User(); - try { - ldapUser = lookupUser(accountName); - if (ldapUser != null) { - Attribute attribute = ldapUser.getAttributes().get(idAttribute); - if (attribute != null) { - user.setLogin((String) attribute.get()); - } else { - user.setLogin(accountName); - } - attribute = ldapUser.getAttributes().get(nameAttribute); - if (attribute != null) { - user.setName((String) attribute.get()); - } else { - user.setName(accountName); - } - attribute = ldapUser.getAttributes().get(mailAttribute); - if (attribute != null) { - user.setEmail((String) attribute.get()); - } else { - user.setEmail(accountName); - } - } - user.setAdministrator(isAdmin(accountName)); - } catch (NamingException e) { - user.setLogin(accountName); - user.setName(accountName); - user.setEmail(accountName); - LOGGER.warn("User lookup error", e); - } - return user; - } - - public boolean login(String username, String password) { - try { - SearchResult ldapUser = lookupUser(username); - if (ldapUser != null) { - auth(ldapUser.getNameInNamespace(), password).close(); - return true; - } - } catch (NamingException e) { - return false; - } - return false; - } - -} diff --git a/src/org/traccar/database/MailManager.java b/src/org/traccar/database/MailManager.java deleted file mode 100644 index 8a2f002cd..000000000 --- a/src/org/traccar/database/MailManager.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.model.User; -import org.traccar.notification.PropertiesProvider; - -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.util.Date; -import java.util.Properties; - -public final class MailManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); - - private static Properties getProperties(PropertiesProvider provider) { - Properties properties = new Properties(); - String host = provider.getString("mail.smtp.host"); - if (host != null) { - properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); - properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); - - Boolean starttlsEnable = provider.getBoolean("mail.smtp.starttls.enable"); - if (starttlsEnable != null) { - properties.put("mail.smtp.starttls.enable", String.valueOf(starttlsEnable)); - } - Boolean starttlsRequired = provider.getBoolean("mail.smtp.starttls.required"); - if (starttlsRequired != null) { - properties.put("mail.smtp.starttls.required", String.valueOf(starttlsRequired)); - } - - Boolean sslEnable = provider.getBoolean("mail.smtp.ssl.enable"); - if (sslEnable != null) { - properties.put("mail.smtp.ssl.enable", String.valueOf(sslEnable)); - } - String sslTrust = provider.getString("mail.smtp.ssl.trust"); - if (sslTrust != null) { - properties.put("mail.smtp.ssl.trust", sslTrust); - } - - String sslProtocols = provider.getString("mail.smtp.ssl.protocols"); - if (sslProtocols != null) { - properties.put("mail.smtp.ssl.protocols", sslProtocols); - } - - String username = provider.getString("mail.smtp.username"); - if (username != null) { - properties.put("mail.smtp.username", username); - } - String password = provider.getString("mail.smtp.password"); - if (password != null) { - properties.put("mail.smtp.password", password); - } - String from = provider.getString("mail.smtp.from"); - if (from != null) { - properties.put("mail.smtp.from", from); - } - } - return properties; - } - - public void sendMessage( - long userId, String subject, String body) throws MessagingException { - sendMessage(userId, subject, body, null); - } - - public void sendMessage( - long userId, String subject, String body, MimeBodyPart attachment) throws MessagingException { - User user = Context.getPermissionsManager().getUser(userId); - - Properties properties = null; - if (!Context.getConfig().getBoolean("mail.smtp.ignoreUserConfig")) { - properties = getProperties(new PropertiesProvider(user)); - } - if (properties == null || !properties.containsKey("mail.smtp.host")) { - properties = getProperties(new PropertiesProvider(Context.getConfig())); - } - if (!properties.containsKey("mail.smtp.host")) { - LOGGER.warn("No SMTP configuration found"); - return; - } - - Session session = Session.getInstance(properties); - - MimeMessage message = new MimeMessage(session); - - String from = properties.getProperty("mail.smtp.from"); - if (from != null) { - message.setFrom(new InternetAddress(from)); - } - - message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); - message.setSubject(subject); - message.setSentDate(new Date()); - - if (attachment != null) { - Multipart multipart = new MimeMultipart(); - - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(body, "text/html; charset=utf-8"); - multipart.addBodyPart(messageBodyPart); - multipart.addBodyPart(attachment); - - message.setContent(multipart); - } else { - message.setContent(body, "text/html; charset=utf-8"); - } - - try (Transport transport = session.getTransport()) { - Main.getInjector().getInstance(StatisticsManager.class).registerMail(); - transport.connect( - properties.getProperty("mail.smtp.host"), - properties.getProperty("mail.smtp.username"), - properties.getProperty("mail.smtp.password")); - transport.sendMessage(message, message.getAllRecipients()); - } - } - -} diff --git a/src/org/traccar/database/MaintenancesManager.java b/src/org/traccar/database/MaintenancesManager.java deleted file mode 100644 index 4e266cb78..000000000 --- a/src/org/traccar/database/MaintenancesManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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/ManagableObjects.java b/src/org/traccar/database/ManagableObjects.java deleted file mode 100644 index ec9549493..000000000 --- a/src/org/traccar/database/ManagableObjects.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.util.Set; - -public interface ManagableObjects { - - Set<Long> getUserItems(long userId); - - Set<Long> getManagedItems(long userId); - -} diff --git a/src/org/traccar/database/MediaManager.java b/src/org/traccar/database/MediaManager.java deleted file mode 100644 index edade5766..000000000 --- a/src/org/traccar/database/MediaManager.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * 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 io.netty.buffer.ByteBuf; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class MediaManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class); - - private String path; - - public MediaManager(String path) { - this.path = path; - } - - private File createFile(String uniqueId, String name) throws IOException { - Path filePath = Paths.get(path, uniqueId, name); - Path directoryPath = filePath.getParent(); - if (directoryPath != null) { - Files.createDirectories(directoryPath); - } - return filePath.toFile(); - } - - 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.nioBuffer(); - int written = 0; - while (written < size) { - written += fileChannel.write(byteBuffer); - } - fileChannel.force(false); - return name; - } catch (IOException e) { - LOGGER.warn("Save media file error", e); - } - } - return null; - } - -} diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java deleted file mode 100644 index 09df4c571..000000000 --- a/src/org/traccar/database/NotificationManager.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - * 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 java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.sql.SQLException; -import java.util.Date; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Calendar; -import org.traccar.model.Event; -import org.traccar.model.Notification; -import org.traccar.model.Position; -import org.traccar.model.Typed; - -public class NotificationManager extends ExtendedObjectManager<Notification> { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); - - private boolean geocodeOnRequest; - - public NotificationManager(DataManager dataManager) { - super(dataManager, Notification.class); - geocodeOnRequest = Context.getConfig().getBoolean("geocoder.onRequest"); - } - - private Set<Long> getEffectiveNotifications(long userId, long deviceId, Date time) { - Set<Long> result = new HashSet<>(); - Set<Long> deviceNotifications = getAllDeviceItems(deviceId); - for (long itemId : getUserItems(userId)) { - if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) { - long calendarId = getById(itemId).getCalendarId(); - Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; - if (calendar == null || calendar.checkMoment(time)) { - result.add(itemId); - } - } - } - return result; - } - - public void updateEvent(Event event, Position position) { - try { - getDataManager().addObject(event); - } catch (SQLException error) { - LOGGER.warn("Event save error", error); - } - - if (position != null && geocodeOnRequest && Context.getGeocoder() != null && position.getAddress() == null) { - position.setAddress(Context.getGeocoder() - .getAddress(position.getLatitude(), position.getLongitude(), null)); - } - - long deviceId = event.getDeviceId(); - Set<Long> users = Context.getPermissionsManager().getDeviceUsers(deviceId); - Set<Long> usersToForward = null; - if (Context.getEventForwarder() != null) { - usersToForward = new HashSet<>(); - } - for (long userId : users) { - 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); - } - final Set<String> notificators = new HashSet<>(); - for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getServerTime())) { - Notification notification = getById(notificationId); - if (getById(notificationId).getType().equals(event.getType())) { - boolean filter = false; - if (event.getType().equals(Event.TYPE_ALARM)) { - String alarms = notification.getString("alarms"); - if (alarms == null || !alarms.contains(event.getString(Position.KEY_ALARM))) { - filter = true; - } - } - if (!filter) { - notificators.addAll(notification.getNotificatorsTypes()); - } - } - } - for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); - } - } - } - if (Context.getEventForwarder() != null) { - Context.getEventForwarder().forwardEvent(event, position, usersToForward); - } - } - - public void updateEvents(Map<Event, Position> events) { - for (Entry<Event, Position> event : events.entrySet()) { - updateEvent(event.getKey(), event.getValue()); - } - } - - public Set<Typed> getAllNotificationTypes() { - Set<Typed> types = new HashSet<>(); - Field[] fields = Event.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - types.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get event types error", error); - } - } - } - return types; - } -} diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java deleted file mode 100644 index ced0df1c0..000000000 --- a/src/org/traccar/database/PermissionsManager.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * 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. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Attribute; -import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; -import org.traccar.model.Command; -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; -import org.traccar.model.Server; -import org.traccar.model.User; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class PermissionsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); - - private final DataManager dataManager; - private final UsersManager usersManager; - - private volatile Server server; - - private final Map<Long, Set<Long>> groupPermissions = new HashMap<>(); - private final Map<Long, Set<Long>> devicePermissions = new HashMap<>(); - private final Map<Long, Set<Long>> deviceUsers = new HashMap<>(); - private final Map<Long, Set<Long>> groupDevices = new HashMap<>(); - - public PermissionsManager(DataManager dataManager, UsersManager usersManager) { - this.dataManager = dataManager; - this.usersManager = usersManager; - refreshServer(); - refreshDeviceAndGroupPermissions(); - } - - public User getUser(long userId) { - return usersManager.getById(userId); - } - - public Set<Long> getGroupPermissions(long userId) { - if (!groupPermissions.containsKey(userId)) { - groupPermissions.put(userId, new HashSet<>()); - } - return groupPermissions.get(userId); - } - - public Set<Long> getDevicePermissions(long userId) { - if (!devicePermissions.containsKey(userId)) { - devicePermissions.put(userId, new HashSet<>()); - } - return devicePermissions.get(userId); - } - - private Set<Long> getAllDeviceUsers(long deviceId) { - if (!deviceUsers.containsKey(deviceId)) { - deviceUsers.put(deviceId, new HashSet<>()); - } - return deviceUsers.get(deviceId); - } - - public Set<Long> getDeviceUsers(long deviceId) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device != null && !device.getDisabled()) { - return getAllDeviceUsers(deviceId); - } else { - Set<Long> result = new HashSet<>(); - for (long userId : getAllDeviceUsers(deviceId)) { - if (getUserAdmin(userId)) { - result.add(userId); - } - } - return result; - } - } - - public Set<Long> getGroupDevices(long groupId) { - if (!groupDevices.containsKey(groupId)) { - groupDevices.put(groupId, new HashSet<>()); - } - return groupDevices.get(groupId); - } - - public void refreshServer() { - try { - server = dataManager.getServer(); - } catch (SQLException error) { - LOGGER.warn("Refresh server config error", error); - } - } - - public final void refreshDeviceAndGroupPermissions() { - groupPermissions.clear(); - devicePermissions.clear(); - try { - GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Context.getGroupsManager().getAllItems()), - Context.getDeviceManager().getAllDevices()); - for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { - Set<Long> userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); - Set<Long> userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); - userGroupPermissions.add(groupPermission.getPropertyId()); - for (Group group : groupTree.getGroups(groupPermission.getPropertyId())) { - userGroupPermissions.add(group.getId()); - } - for (Device device : groupTree.getDevices(groupPermission.getPropertyId())) { - userDevicePermissions.add(device.getId()); - } - } - - for (Permission devicePermission : dataManager.getPermissions(User.class, Device.class)) { - getDevicePermissions(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); - } - - groupDevices.clear(); - for (long groupId : Context.getGroupsManager().getAllItems()) { - for (Device device : groupTree.getDevices(groupId)) { - getGroupDevices(groupId).add(device.getId()); - } - } - - } catch (SQLException | ClassNotFoundException error) { - LOGGER.warn("Refresh device permissions error", error); - } - - deviceUsers.clear(); - for (Map.Entry<Long, Set<Long>> entry : devicePermissions.entrySet()) { - for (long deviceId : entry.getValue()) { - getAllDeviceUsers(deviceId).add(entry.getKey()); - } - } - } - - public boolean getUserAdmin(long userId) { - User user = getUser(userId); - return user != null && user.getAdministrator(); - } - - public void checkAdmin(long userId) throws SecurityException { - if (!getUserAdmin(userId)) { - throw new SecurityException("Admin access required"); - } - } - - public boolean getUserManager(long userId) { - User user = getUser(userId); - return user != null && user.getUserLimit() != 0; - } - - public void checkManager(long userId) throws SecurityException { - if (!getUserManager(userId)) { - throw new SecurityException("Manager access required"); - } - } - - public void checkManager(long userId, long managedUserId) throws SecurityException { - checkManager(userId); - if (!usersManager.getUserItems(userId).contains(managedUserId)) { - throw new SecurityException("User access denied"); - } - } - - public void checkUserLimit(long userId) throws SecurityException { - int userLimit = getUser(userId).getUserLimit(); - if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) { - throw new SecurityException("Manager user limit reached"); - } - } - - public void checkDeviceLimit(long userId) throws SecurityException { - int deviceLimit = getUser(userId).getDeviceLimit(); - if (deviceLimit != -1) { - int deviceCount = 0; - if (getUserManager(userId)) { - deviceCount = Context.getDeviceManager().getAllManagedItems(userId).size(); - } else { - deviceCount = Context.getDeviceManager().getAllUserItems(userId).size(); - } - if (deviceCount >= deviceLimit) { - throw new SecurityException("User device limit reached"); - } - } - } - - public boolean getUserReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getReadonly(); - } - - public boolean getUserDeviceReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getDeviceReadonly(); - } - - public boolean getUserLimitCommands(long userId) { - User user = getUser(userId); - return user != null && user.getLimitCommands(); - } - - public void checkReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { - throw new SecurityException("Account is readonly"); - } - } - - public void checkDeviceReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getDeviceReadonly() || getUserDeviceReadonly(userId))) { - throw new SecurityException("Account is device readonly"); - } - } - - public void checkLimitCommands(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) { - throw new SecurityException("Account has limit sending commands"); - } - } - - public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { - if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { - throw new SecurityException("Command can not be sent to this device"); - } - } - - public void checkUserEnabled(long userId) throws SecurityException { - User user = getUser(userId); - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - - public void checkUserUpdate(long userId, User before, User after) throws SecurityException { - if (before.getAdministrator() != after.getAdministrator() - || before.getDeviceLimit() != after.getDeviceLimit() - || before.getUserLimit() != after.getUserLimit()) { - checkAdmin(userId); - } - User user = getUser(userId); - if (user != null && user.getExpirationTime() != null - && (after.getExpirationTime() == null - || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { - checkAdmin(userId); - } - if (before.getReadonly() != after.getReadonly() - || before.getDeviceReadonly() != after.getDeviceReadonly() - || before.getDisabled() != after.getDisabled() - || before.getLimitCommands() != after.getLimitCommands()) { - if (userId == after.getId()) { - checkAdmin(userId); - } - if (!getUserAdmin(userId)) { - checkManager(userId); - } - } - } - - public void checkUser(long userId, long managedUserId) throws SecurityException { - if (userId != managedUserId && !getUserAdmin(userId)) { - checkManager(userId, managedUserId); - } - } - - public void checkGroup(long userId, long groupId) throws SecurityException { - if (!getGroupPermissions(userId).contains(groupId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (getGroupPermissions(managedUserId).contains(groupId)) { - return; - } - } - throw new SecurityException("Group access denied"); - } - } - - public void checkDevice(long userId, long deviceId) throws SecurityException { - if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) { - return; - } - } - throw new SecurityException("Device access denied"); - } - } - - public void checkRegistration(long userId) { - if (!server.getRegistration() && !getUserAdmin(userId)) { - throw new SecurityException("Registration disabled"); - } - } - - public void checkPermission(Class<?> object, long userId, long objectId) - throws SecurityException { - SimpleObjectManager<? extends BaseModel> manager = null; - - if (object.equals(Device.class)) { - checkDevice(userId, objectId); - } else if (object.equals(Group.class)) { - checkGroup(userId, objectId); - } else if (object.equals(User.class) || object.equals(ManagedUser.class)) { - checkUser(userId, objectId); - } else if (object.equals(Geofence.class)) { - manager = Context.getGeofenceManager(); - } else if (object.equals(Attribute.class)) { - manager = Context.getAttributesManager(); - } else if (object.equals(Driver.class)) { - manager = Context.getDriversManager(); - } else if (object.equals(Calendar.class)) { - 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 { - throw new IllegalArgumentException("Unknown object type"); - } - - if (manager != null && !manager.checkItemPermission(userId, objectId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getManagedItems(userId)) { - if (manager.checkItemPermission(managedUserId, objectId)) { - return; - } - } - throw new SecurityException("Type " + object + " access denied"); - } - } - - public void refreshAllUsersPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); - } - Context.getCalendarManager().refreshUserItems(); - Context.getDriversManager().refreshUserItems(); - Context.getAttributesManager().refreshUserItems(); - Context.getCommandsManager().refreshUserItems(); - Context.getMaintenancesManager().refreshUserItems(); - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshUserItems(); - } - } - - public void refreshAllExtendedPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } - Context.getDriversManager().refreshExtendedPermissions(); - Context.getAttributesManager().refreshExtendedPermissions(); - Context.getCommandsManager().refreshExtendedPermissions(); - Context.getMaintenancesManager().refreshExtendedPermissions(); - } - - public void refreshPermissions(Permission permission) { - if (permission.getOwnerClass().equals(User.class)) { - if (permission.getPropertyClass().equals(Device.class) - || permission.getPropertyClass().equals(Group.class)) { - refreshDeviceAndGroupPermissions(); - refreshAllExtendedPermissions(); - } else if (permission.getPropertyClass().equals(ManagedUser.class)) { - usersManager.refreshUserItems(); - } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - Context.getAttributesManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Calendar.class)) { - 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(); - } - } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { - if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - 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(); - } - } - } - - public Server getServer() { - return server; - } - - public void updateServer(Server server) throws SQLException { - dataManager.updateObject(server); - this.server = server; - } - - public User login(String email, String password) throws SQLException { - User user = dataManager.login(email, password); - if (user != null) { - checkUserEnabled(user.getId()); - return getUser(user.getId()); - } - return null; - } - - public Object lookupAttribute(long userId, String key, Object defaultValue) { - Object preference; - Object serverPreference = server.getAttributes().get(key); - Object userPreference = getUser(userId).getAttributes().get(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - -} diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java deleted file mode 100644 index 5528b2320..000000000 --- a/src/org/traccar/database/QueryBuilder.java +++ /dev/null @@ -1,519 +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.database; - -import com.fasterxml.jackson.core.JsonProcessingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.MiscFormatter; -import org.traccar.model.Permission; - -import javax.sql.DataSource; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public final class QueryBuilder { - - private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); - - private final Map<String, List<Integer>> indexMap = new HashMap<>(); - private Connection connection; - private PreparedStatement statement; - private final String query; - private final boolean returnGeneratedKeys; - - private QueryBuilder(DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - this.query = query; - this.returnGeneratedKeys = returnGeneratedKeys; - if (query != null) { - connection = dataSource.getConnection(); - String parsedQuery = parse(query.trim(), indexMap); - try { - if (returnGeneratedKeys) { - statement = connection.prepareStatement(parsedQuery, Statement.RETURN_GENERATED_KEYS); - } else { - statement = connection.prepareStatement(parsedQuery); - } - } catch (SQLException error) { - connection.close(); - throw error; - } - } - } - - private static String parse(String query, Map<String, List<Integer>> paramMap) { - - int length = query.length(); - StringBuilder parsedQuery = new StringBuilder(length); - boolean inSingleQuote = false; - boolean inDoubleQuote = false; - int index = 1; - - for (int i = 0; i < length; i++) { - - char c = query.charAt(i); - - // String end - if (inSingleQuote) { - if (c == '\'') { - inSingleQuote = false; - } - } else if (inDoubleQuote) { - if (c == '"') { - inDoubleQuote = false; - } - } else { - - // String begin - if (c == '\'') { - inSingleQuote = true; - } else if (c == '"') { - inDoubleQuote = true; - } else if (c == ':' && i + 1 < length - && Character.isJavaIdentifierStart(query.charAt(i + 1))) { - - // Identifier name - int j = i + 2; - while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) { - j++; - } - - String name = query.substring(i + 1, j); - c = '?'; - i += name.length(); - name = name.toLowerCase(); - - // Add to list - List<Integer> indexList = paramMap.get(name); - if (indexList == null) { - indexList = new LinkedList<>(); - paramMap.put(name, indexList); - } - indexList.add(index); - - index++; - } - } - - parsedQuery.append(c); - } - - return parsedQuery.toString(); - } - - public static QueryBuilder create(DataSource dataSource, String query) throws SQLException { - return new QueryBuilder(dataSource, query, false); - } - - public static QueryBuilder create( - DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, query, returnGeneratedKeys); - } - - private List<Integer> indexes(String name) { - name = name.toLowerCase(); - List<Integer> result = indexMap.get(name); - if (result == null) { - result = new LinkedList<>(); - } - return result; - } - - public QueryBuilder setBoolean(String name, boolean value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setBoolean(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setInteger(String name, int value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setInt(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setLong(String name, long value) throws SQLException { - return setLong(name, value, false); - } - - public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == 0 && nullIfZero) { - statement.setNull(i, Types.INTEGER); - } else { - statement.setLong(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setDouble(String name, double value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setDouble(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setString(String name, String value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.VARCHAR); - } else { - statement.setString(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setDate(String name, Date value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.TIMESTAMP); - } else { - statement.setTimestamp(i, new Timestamp(value.getTime())); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setBlob(String name, byte[] value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.BLOB); - } else { - statement.setBytes(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setObject(Object object) throws SQLException { - - Method[] methods = object.getClass().getMethods(); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 - && !method.isAnnotationPresent(QueryIgnore.class)) { - String name = method.getName().substring(3); - try { - if (method.getReturnType().equals(boolean.class)) { - setBoolean(name, (Boolean) method.invoke(object)); - } else if (method.getReturnType().equals(int.class)) { - setInteger(name, (Integer) method.invoke(object)); - } else if (method.getReturnType().equals(long.class)) { - setLong(name, (Long) method.invoke(object), name.endsWith("Id")); - } else if (method.getReturnType().equals(double.class)) { - setDouble(name, (Double) method.invoke(object)); - } else if (method.getReturnType().equals(String.class)) { - setString(name, (String) method.invoke(object)); - } else if (method.getReturnType().equals(Date.class)) { - setDate(name, (Date) method.invoke(object)); - } else if (method.getReturnType().equals(byte[].class)) { - setBlob(name, (byte[]) method.invoke(object)); - } else { - if (method.getReturnType().equals(Map.class) - && Context.getConfig().getBoolean("database.xml")) { - setString(name, MiscFormatter.toXmlString((Map) method.invoke(object))); - } else { - setString(name, Context.getObjectMapper().writeValueAsString(method.invoke(object))); - } - } - } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { - LOGGER.warn("Get property error", error); - } - } - } - - return this; - } - - private interface ResultSetProcessor<T> { - void process(T object, ResultSet resultSet) throws SQLException; - } - - public <T> T executeQuerySingle(Class<T> clazz) throws SQLException { - Collection<T> result = executeQuery(clazz); - if (!result.isEmpty()) { - return result.iterator().next(); - } else { - return null; - } - } - - private <T> void addProcessors( - List<ResultSetProcessor<T>> processors, - final Class<?> parameterType, final Method method, final String name) { - - if (parameterType.equals(boolean.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getBoolean(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(int.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getInt(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(long.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getLong(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(double.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getDouble(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(String.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getString(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(Date.class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - Timestamp timestamp = resultSet.getTimestamp(name); - if (timestamp != null) { - method.invoke(object, new Date(timestamp.getTime())); - } - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else if (parameterType.equals(byte[].class)) { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - try { - method.invoke(object, resultSet.getBytes(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } else { - processors.add(new ResultSetProcessor<T>() { - @Override - public void process(T object, ResultSet resultSet) throws SQLException { - String value = resultSet.getString(name); - if (value != null && !value.isEmpty()) { - try { - method.invoke(object, Context.getObjectMapper().readValue(value, parameterType)); - } catch (InvocationTargetException | IllegalAccessException | IOException error) { - LOGGER.warn("Set property error", error); - } - } - } - }); - } - } - - public <T> Collection<T> executeQuery(Class<T> clazz) throws SQLException { - List<T> result = new LinkedList<>(); - - if (query != null) { - - try { - - try (ResultSet resultSet = statement.executeQuery()) { - - ResultSetMetaData resultMetaData = resultSet.getMetaData(); - - List<ResultSetProcessor<T>> processors = new LinkedList<>(); - - Method[] methods = clazz.getMethods(); - - for (final Method method : methods) { - if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 - && !method.isAnnotationPresent(QueryIgnore.class)) { - - final String name = method.getName().substring(3); - - // Check if column exists - boolean column = false; - for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { - if (name.equalsIgnoreCase(resultMetaData.getColumnLabel(i))) { - column = true; - break; - } - } - if (!column) { - continue; - } - - addProcessors(processors, method.getParameterTypes()[0], method, name); - } - } - - while (resultSet.next()) { - try { - T object = clazz.newInstance(); - for (ResultSetProcessor<T> processor : processors) { - processor.process(object, resultSet); - } - result.add(object); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalArgumentException(); - } - } - } - - } finally { - statement.close(); - connection.close(); - } - } - - return result; - } - - public long executeUpdate() throws SQLException { - - if (query != null) { - try { - statement.execute(); - if (returnGeneratedKeys) { - ResultSet resultSet = statement.getGeneratedKeys(); - if (resultSet.next()) { - return resultSet.getLong(1); - } - } - } finally { - statement.close(); - connection.close(); - } - } - return 0; - } - - public Collection<Permission> executePermissionsQuery() throws SQLException, ClassNotFoundException { - List<Permission> result = new LinkedList<>(); - if (query != null) { - try { - try (ResultSet resultSet = statement.executeQuery()) { - ResultSetMetaData resultMetaData = resultSet.getMetaData(); - while (resultSet.next()) { - LinkedHashMap<String, Long> map = new LinkedHashMap<>(); - for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { - String label = resultMetaData.getColumnLabel(i); - map.put(label, resultSet.getLong(label)); - } - result.add(new Permission(map)); - } - } - } finally { - statement.close(); - connection.close(); - } - } - - return result; - } - -} diff --git a/src/org/traccar/database/QueryExtended.java b/src/org/traccar/database/QueryExtended.java deleted file mode 100644 index 07bc2c211..000000000 --- a/src/org/traccar/database/QueryExtended.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryExtended { -} diff --git a/src/org/traccar/database/QueryIgnore.java b/src/org/traccar/database/QueryIgnore.java deleted file mode 100644 index ac835cf2f..000000000 --- a/src/org/traccar/database/QueryIgnore.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.database; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryIgnore { -} diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java deleted file mode 100644 index 15dda4520..000000000 --- a/src/org/traccar/database/SimpleObjectManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.sql.SQLException; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.BaseModel; -import org.traccar.model.Permission; -import org.traccar.model.User; - -public abstract class SimpleObjectManager<T extends BaseModel> extends BaseObjectManager<T> - implements ManagableObjects { - - private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class); - - private Map<Long, Set<Long>> userItems; - - protected SimpleObjectManager(DataManager dataManager, Class<T> baseClass) { - super(dataManager, baseClass); - } - - @Override - public final Set<Long> getUserItems(long userId) { - if (!userItems.containsKey(userId)) { - userItems.put(userId, new HashSet<Long>()); - } - return userItems.get(userId); - } - - @Override - public Set<Long> getManagedItems(long userId) { - Set<Long> result = new HashSet<>(); - result.addAll(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - - public final boolean checkItemPermission(long userId, long itemId) { - return getUserItems(userId).contains(itemId); - } - - @Override - public void refreshItems() { - super.refreshItems(); - refreshUserItems(); - } - - public final void refreshUserItems() { - if (getDataManager() != null) { - try { - if (userItems != null) { - userItems.clear(); - } else { - userItems = new ConcurrentHashMap<>(); - } - for (Permission permission : getDataManager().getPermissions(User.class, getBaseClass())) { - getUserItems(permission.getOwnerId()).add(permission.getPropertyId()); - } - } catch (SQLException | ClassNotFoundException error) { - LOGGER.warn("Error getting permissions", error); - } - } - } - - @Override - public void removeItem(long itemId) throws SQLException { - super.removeItem(itemId); - refreshUserItems(); - } - -} diff --git a/src/org/traccar/database/StatisticsManager.java b/src/org/traccar/database/StatisticsManager.java deleted file mode 100644 index e59f8e767..000000000 --- a/src/org/traccar/database/StatisticsManager.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.DateUtil; -import org.traccar.model.Statistics; - -import javax.inject.Inject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Form; -import java.sql.SQLException; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class StatisticsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsManager.class); - - private static final int SPLIT_MODE = Calendar.DAY_OF_MONTH; - - private final Config config; - private final DataManager dataManager; - private final Client client; - - private AtomicInteger lastUpdate = new AtomicInteger(Calendar.getInstance().get(SPLIT_MODE)); - - private Set<Long> users = new HashSet<>(); - private Set<Long> devices = new HashSet<>(); - - private int requests; - private int messagesReceived; - private int messagesStored; - private int mailSent; - private int smsSent; - private int geocoderRequests; - private int geolocationRequests; - - @Inject - public StatisticsManager(Config config, DataManager dataManager, Client client) { - this.config = config; - this.dataManager = dataManager; - this.client = client; - } - - private void checkSplit() { - int currentUpdate = Calendar.getInstance().get(SPLIT_MODE); - if (lastUpdate.getAndSet(currentUpdate) != currentUpdate) { - Statistics statistics = new Statistics(); - statistics.setCaptureTime(new Date()); - statistics.setActiveUsers(users.size()); - statistics.setActiveDevices(devices.size()); - statistics.setRequests(requests); - statistics.setMessagesReceived(messagesReceived); - statistics.setMessagesStored(messagesStored); - statistics.setMailSent(mailSent); - statistics.setSmsSent(smsSent); - statistics.setGeocoderRequests(geocoderRequests); - statistics.setGeolocationRequests(geolocationRequests); - - try { - dataManager.addObject(statistics); - } catch (SQLException e) { - LOGGER.warn("Error saving statistics", e); - } - - String url = config.getString(Keys.SERVER_STATISTICS); - if (url != null) { - String time = DateUtil.formatDate(statistics.getCaptureTime()); - - Form form = new Form(); - form.param("version", getClass().getPackage().getImplementationVersion()); - 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())); - - client.target(url).request().async().post(Entity.form(form)); - } - - users.clear(); - devices.clear(); - requests = 0; - messagesReceived = 0; - messagesStored = 0; - mailSent = 0; - smsSent = 0; - geocoderRequests = 0; - geolocationRequests = 0; - } - } - - public synchronized void registerRequest(long userId) { - checkSplit(); - requests += 1; - if (userId != 0) { - users.add(userId); - } - } - - public synchronized void registerMessageReceived() { - checkSplit(); - messagesReceived += 1; - } - - public synchronized void registerMessageStored(long deviceId) { - checkSplit(); - messagesStored += 1; - if (deviceId != 0) { - devices.add(deviceId); - } - } - - public synchronized void registerMail() { - checkSplit(); - mailSent += 1; - } - - public synchronized void registerSms() { - checkSplit(); - smsSent += 1; - } - - public synchronized void registerGeocoderRequest() { - checkSplit(); - geocoderRequests += 1; - } - - public synchronized void registerGeolocationRequest() { - checkSplit(); - geolocationRequests += 1; - } - -} diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java deleted file mode 100644 index 576a9e6c7..000000000 --- a/src/org/traccar/database/UsersManager.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.User; - -public class UsersManager extends SimpleObjectManager<User> { - - private Map<String, User> usersTokens; - - public UsersManager(DataManager dataManager) { - super(dataManager, User.class); - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - } - - private void putToken(User user) { - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user); - } - } - - @Override - protected void addNewItem(User user) { - super.addNewItem(user); - putToken(user); - } - - @Override - protected void updateCachedItem(User user) { - User cachedUser = getById(user.getId()); - super.updateCachedItem(user); - putToken(user); - if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) { - usersTokens.remove(cachedUser.getToken()); - } - } - - @Override - protected void removeCachedItem(long userId) { - User cachedUser = getById(userId); - if (cachedUser != null) { - String userToken = cachedUser.getToken(); - super.removeCachedItem(userId); - if (userToken != null) { - usersTokens.remove(userToken); - } - } - } - - @Override - public Set<Long> getManagedItems(long userId) { - Set<Long> result = new HashSet<>(); - result.addAll(getUserItems(userId)); - result.add(userId); - return result; - } - - public User getUserByToken(String token) { - return usersTokens.get(token); - } - -} diff --git a/src/org/traccar/geocoder/Address.java b/src/org/traccar/geocoder/Address.java deleted file mode 100644 index fe39da8e1..000000000 --- a/src/org/traccar/geocoder/Address.java +++ /dev/null @@ -1,110 +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.geocoder; - -public class Address { - - private String postcode; - - public String getPostcode() { - return postcode; - } - - public void setPostcode(String postcode) { - this.postcode = postcode; - } - - private String country; - - public String getCountry() { - return country; - } - - public void setCountry(String country) { - this.country = country; - } - - private String state; - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - private String district; - - public String getDistrict() { - return district; - } - - public void setDistrict(String district) { - this.district = district; - } - - private String settlement; - - public String getSettlement() { - return settlement; - } - - public void setSettlement(String settlement) { - this.settlement = settlement; - } - - private String suburb; - - public String getSuburb() { - return suburb; - } - - public void setSuburb(String suburb) { - this.suburb = suburb; - } - - private String street; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - - private String house; - - public String getHouse() { - return house; - } - - public void setHouse(String house) { - this.house = house; - } - - private String formattedAddress; - - public String getFormattedAddress() { - return formattedAddress; - } - - public void setFormattedAddress(String formattedAddress) { - this.formattedAddress = formattedAddress; - } - -} diff --git a/src/org/traccar/geocoder/AddressFormat.java b/src/org/traccar/geocoder/AddressFormat.java deleted file mode 100644 index ad19432b9..000000000 --- a/src/org/traccar/geocoder/AddressFormat.java +++ /dev/null @@ -1,82 +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.geocoder; - -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; - -/** - * Available parameters: - * - * %p - postcode - * %c - country - * %s - state - * %d - district - * %t - settlement (town) - * %u - suburb - * %r - street (road) - * %h - house - * %f - formatted address - * - */ -public class AddressFormat extends Format { - - private final String format; - - public AddressFormat() { - this("%h %r, %t, %s, %c"); - } - - public AddressFormat(String format) { - this.format = format; - } - - private static String replace(String s, String key, String value) { - if (value != null) { - s = s.replace(key, value); - } else { - s = s.replaceAll("[, ]*" + key, ""); - } - return s; - } - - @Override - public StringBuffer format(Object o, StringBuffer stringBuffer, FieldPosition fieldPosition) { - Address address = (Address) o; - String result = format; - - result = replace(result, "%p", address.getPostcode()); - result = replace(result, "%c", address.getCountry()); - result = replace(result, "%s", address.getState()); - result = replace(result, "%d", address.getDistrict()); - result = replace(result, "%t", address.getSettlement()); - result = replace(result, "%u", address.getSuburb()); - result = replace(result, "%r", address.getStreet()); - result = replace(result, "%h", address.getHouse()); - result = replace(result, "%f", address.getFormattedAddress()); - - result = result.replaceAll("^[, ]*", ""); - - return stringBuffer.append(result); - } - - @Override - public Address parseObject(String s, ParsePosition parsePosition) { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/org/traccar/geocoder/BanGeocoder.java b/src/org/traccar/geocoder/BanGeocoder.java deleted file mode 100644 index b1f0900a4..000000000 --- a/src/org/traccar/geocoder/BanGeocoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 Olivier Girondel (olivier@biniou.info) - * 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; - -/* - * API documentation: https://adresse.data.gouv.fr/api - */ - -import javax.json.JsonArray; -import javax.json.JsonObject; - -public class BanGeocoder extends JsonGeocoder { - - public BanGeocoder(int cacheSize, AddressFormat addressFormat) { - super("https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("features"); - - if (result != null && !result.isEmpty()) { - JsonObject location = result.getJsonObject(0).getJsonObject("properties"); - Address address = new Address(); - - address.setCountry("FR"); - if (location.containsKey("postcode")) { - address.setPostcode(location.getString("postcode")); - } - if (location.containsKey("context")) { - address.setDistrict(location.getString("context")); - } - if (location.containsKey("name")) { - address.setStreet(location.getString("name")); - } - if (location.containsKey("city")) { - address.setSettlement(location.getString("city")); - } - if (location.containsKey("housenumber")) { - address.setHouse(location.getString("housenumber")); - } - if (location.containsKey("label")) { - address.setFormattedAddress(location.getString("label")); - } - - return address; - } - - return null; - } - -} diff --git a/src/org/traccar/geocoder/BingMapsGeocoder.java b/src/org/traccar/geocoder/BingMapsGeocoder.java deleted file mode 100644 index 32a26ee0c..000000000 --- a/src/org/traccar/geocoder/BingMapsGeocoder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.geocoder; - -import javax.json.JsonArray; -import javax.json.JsonObject; - -public class BingMapsGeocoder extends JsonGeocoder { - - public BingMapsGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("resourceSets"); - if (result != null) { - JsonObject location = - result.getJsonObject(0).getJsonArray("resources").getJsonObject(0).getJsonObject("address"); - if (location != null) { - Address address = new Address(); - if (location.containsKey("addressLine")) { - address.setStreet(location.getString("addressLine")); - } - if (location.containsKey("locality")) { - address.setSettlement(location.getString("locality")); - } - if (location.containsKey("adminDistrict2")) { - address.setDistrict(location.getString("adminDistrict2")); - } - if (location.containsKey("adminDistrict")) { - address.setState(location.getString("adminDistrict")); - } - if (location.containsKey("countryRegionIso2")) { - address.setCountry(location.getString("countryRegionIso2").toUpperCase()); - } - if (location.containsKey("postalCode")) { - address.setPostcode(location.getString("postalCode")); - } - if (location.containsKey("formattedAddress")) { - address.setFormattedAddress(location.getString("formattedAddress")); - } - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geocoder/FactualGeocoder.java b/src/org/traccar/geocoder/FactualGeocoder.java deleted file mode 100644 index c7a68c293..000000000 --- a/src/org/traccar/geocoder/FactualGeocoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.geocoder; - -import javax.json.JsonObject; - -public class FactualGeocoder extends JsonGeocoder { - - public FactualGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "?latitude=%f&longitude=%f&KEY=" + key, cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonObject result = json.getJsonObject("response").getJsonObject("data"); - if (result != null) { - Address address = new Address(); - if (result.getJsonObject("street_number") != null) { - address.setHouse(result.getJsonObject("street_number").getString("name")); - } - if (result.getJsonObject("street_name") != null) { - address.setStreet(result.getJsonObject("street_name").getString("name")); - } - if (result.getJsonObject("locality") != null) { - address.setSettlement(result.getJsonObject("locality").getString("name")); - } - if (result.getJsonObject("county") != null) { - address.setDistrict(result.getJsonObject("county").getString("name")); - } - if (result.getJsonObject("region") != null) { - address.setState(result.getJsonObject("region").getString("name")); - } - if (result.getJsonObject("country") != null) { - address.setCountry(result.getJsonObject("country").getString("name")); - } - if (result.getJsonObject("postcode") != null) { - address.setPostcode(result.getJsonObject("postcode").getString("name")); - } - return address; - } - return null; - } - -} diff --git a/src/org/traccar/geocoder/GeocodeFarmGeocoder.java b/src/org/traccar/geocoder/GeocodeFarmGeocoder.java deleted file mode 100644 index 39a3300a0..000000000 --- a/src/org/traccar/geocoder/GeocodeFarmGeocoder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 GeocodeFarmGeocoder extends JsonGeocoder { - - private static String formatUrl(String key, String language) { - String url = "https://www.geocode.farm/v3/json/reverse/"; - url += "?lat=%f&lon=%f&country=us&count=1"; - if (key != null) { - url += "&key=" + key; - } - if (language != null) { - url += "&lang=" + language; - } - return url; - } - public GeocodeFarmGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - Address address = new Address(); - - JsonObject result = json - .getJsonObject("geocoding_results") - .getJsonArray("RESULTS") - .getJsonObject(0); - - JsonObject resultAddress = result.getJsonObject("ADDRESS"); - - if (result.containsKey("formatted_address")) { - address.setFormattedAddress(result.getString("formatted_address")); - } - if (resultAddress.containsKey("street_number")) { - address.setStreet(resultAddress.getString("street_number")); - } - if (resultAddress.containsKey("street_name")) { - address.setStreet(resultAddress.getString("street_name")); - } - if (resultAddress.containsKey("locality")) { - address.setSettlement(resultAddress.getString("locality")); - } - if (resultAddress.containsKey("admin_1")) { - address.setState(resultAddress.getString("admin_1")); - } - if (resultAddress.containsKey("country")) { - address.setCountry(resultAddress.getString("country")); - } - - return address; - } - -} diff --git a/src/org/traccar/geocoder/GeocodeXyzGeocoder.java b/src/org/traccar/geocoder/GeocodeXyzGeocoder.java deleted file mode 100644 index aca360c3d..000000000 --- a/src/org/traccar/geocoder/GeocodeXyzGeocoder.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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/Geocoder.java b/src/org/traccar/geocoder/Geocoder.java deleted file mode 100644 index 587a27520..000000000 --- a/src/org/traccar/geocoder/Geocoder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -public interface Geocoder { - - interface ReverseGeocoderCallback { - - void onSuccess(String address); - - void onFailure(Throwable e); - - } - - String getAddress(double latitude, double longitude, ReverseGeocoderCallback callback); - -} diff --git a/src/org/traccar/geocoder/GeocoderException.java b/src/org/traccar/geocoder/GeocoderException.java deleted file mode 100644 index 608916641..000000000 --- a/src/org/traccar/geocoder/GeocoderException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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; - -public class GeocoderException extends RuntimeException { - - public GeocoderException(String message) { - super(message); - } - -} diff --git a/src/org/traccar/geocoder/GisgraphyGeocoder.java b/src/org/traccar/geocoder/GisgraphyGeocoder.java deleted file mode 100644 index 3a173f985..000000000 --- a/src/org/traccar/geocoder/GisgraphyGeocoder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 GisgraphyGeocoder extends JsonGeocoder { - - public GisgraphyGeocoder(AddressFormat addressFormat) { - this("http://services.gisgraphy.com/reversegeocoding/search", 0, addressFormat); - } - - public GisgraphyGeocoder(String url, int cacheSize, AddressFormat addressFormat) { - super(url + "?format=json&lat=%f&lng=%f&from=1&to=1", cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - Address address = new Address(); - - JsonObject result = json.getJsonArray("result").getJsonObject(0); - - if (result.containsKey("streetName")) { - address.setStreet(result.getString("streetName")); - } - if (result.containsKey("city")) { - address.setSettlement(result.getString("city")); - } - if (result.containsKey("state")) { - address.setState(result.getString("state")); - } - if (result.containsKey("countryCode")) { - address.setCountry(result.getString("countryCode")); - } - if (result.containsKey("formatedFull")) { - address.setFormattedAddress(result.getString("formatedFull")); - } - - return address; - } - -} diff --git a/src/org/traccar/geocoder/GoogleGeocoder.java b/src/org/traccar/geocoder/GoogleGeocoder.java deleted file mode 100644 index 9494cab45..000000000 --- a/src/org/traccar/geocoder/GoogleGeocoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.JsonArray; -import javax.json.JsonObject; -import javax.json.JsonString; - -public class GoogleGeocoder extends JsonGeocoder { - - private static String formatUrl(String key, String language) { - String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"; - if (key != null) { - url += "&key=" + key; - } - if (language != null) { - url += "&language=" + language; - } - return url; - } - - public GoogleGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray results = json.getJsonArray("results"); - - if (!results.isEmpty()) { - Address address = new Address(); - - JsonObject result = (JsonObject) results.get(0); - JsonArray components = result.getJsonArray("address_components"); - - if (result.containsKey("formatted_address")) { - address.setFormattedAddress(result.getString("formatted_address")); - } - - for (JsonObject component : components.getValuesAs(JsonObject.class)) { - - String value = component.getString("short_name"); - - typesLoop: for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) { - - switch (type.getString()) { - case "street_number": - address.setHouse(value); - break typesLoop; - case "route": - address.setStreet(value); - break typesLoop; - case "locality": - address.setSettlement(value); - break typesLoop; - case "administrative_area_level_2": - address.setDistrict(value); - break typesLoop; - case "administrative_area_level_1": - address.setState(value); - break typesLoop; - case "country": - address.setCountry(value); - break typesLoop; - case "postal_code": - address.setPostcode(value); - break typesLoop; - default: - break; - } - } - } - - return address; - } - - return null; - } - - @Override - protected String parseError(JsonObject json) { - return json.getString("error_message"); - } - -} diff --git a/src/org/traccar/geocoder/HereGeocoder.java b/src/org/traccar/geocoder/HereGeocoder.java deleted file mode 100644 index 756260b52..000000000 --- a/src/org/traccar/geocoder/HereGeocoder.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 HereGeocoder extends JsonGeocoder { - - private static String formatUrl(String id, String key, String language) { - String url = "https://reverse.geocoder.api.here.com/6.2/reversegeocode.json"; - url += "?mode=retrieveAddresses&maxresults=1"; - url += "&prox=%f,%f,0"; - url += "&app_id=" + id; - url += "&app_code=" + key; - if (language != null) { - url += "&language=" + language; - } - return url; - } - - public HereGeocoder(String id, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(id, key, language), cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonObject result = json - .getJsonObject("Response") - .getJsonArray("View") - .getJsonObject(0) - .getJsonArray("Result") - .getJsonObject(0) - .getJsonObject("Location") - .getJsonObject("Address"); - - if (result != null) { - Address address = new Address(); - - if (json.containsKey("Label")) { - address.setFormattedAddress(json.getString("Label")); - } - - if (result.containsKey("HouseNumber")) { - address.setHouse(result.getString("HouseNumber")); - } - if (result.containsKey("Street")) { - address.setStreet(result.getString("Street")); - } - if (result.containsKey("City")) { - address.setSettlement(result.getString("City")); - } - if (result.containsKey("District")) { - address.setDistrict(result.getString("District")); - } - if (result.containsKey("State")) { - address.setState(result.getString("State")); - } - if (result.containsKey("Country")) { - address.setCountry(result.getString("Country").toUpperCase()); - } - if (result.containsKey("PostalCode")) { - address.setPostcode(result.getString("PostalCode")); - } - - return address; - } - - return null; - } - -} diff --git a/src/org/traccar/geocoder/JsonGeocoder.java b/src/org/traccar/geocoder/JsonGeocoder.java deleted file mode 100644 index ed59a1d8d..000000000 --- a/src/org/traccar/geocoder/JsonGeocoder.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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. - * 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 org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; - -import javax.json.JsonObject; -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; - -public abstract class JsonGeocoder implements Geocoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonGeocoder.class); - - private final String url; - private final AddressFormat addressFormat; - - private Map<Map.Entry<Double, Double>, String> cache; - - public JsonGeocoder(String url, final int cacheSize, AddressFormat addressFormat) { - this.url = url; - this.addressFormat = addressFormat; - if (cacheSize > 0) { - this.cache = Collections.synchronizedMap(new LinkedHashMap<Map.Entry<Double, Double>, String>() { - @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > cacheSize; - } - }); - } - } - - 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 { - String msg = "Empty address. Error: " + parseError(json); - if (callback != null) { - callback.onFailure(new GeocoderException(msg)); - } else { - LOGGER.warn(msg); - } - } - return null; - } - - @Override - public String getAddress( - final double latitude, final double longitude, final ReverseGeocoderCallback callback) { - - if (cache != null) { - String cachedAddress = cache.get(new AbstractMap.SimpleImmutableEntry<>(latitude, longitude)); - if (cachedAddress != null) { - if (callback != null) { - callback.onSuccess(cachedAddress); - } - return cachedAddress; - } - } - - Invocation.Builder request = Context.getClient().target(String.format(url, latitude, longitude)).request(); - - if (callback != null) { - request.async().get(new InvocationCallback<JsonObject>() { - @Override - public void completed(JsonObject json) { - handleResponse(latitude, longitude, json, callback); - } - - @Override - public void failed(Throwable throwable) { - callback.onFailure(throwable); - } - }); - } else { - try { - return handleResponse(latitude, longitude, request.get(JsonObject.class), null); - } catch (ClientErrorException e) { - LOGGER.warn("Geocoder network error", e); - } - } - return null; - } - - public abstract Address parseAddress(JsonObject json); - - protected String parseError(JsonObject json) { - return null; - } - -} diff --git a/src/org/traccar/geocoder/MapQuestGeocoder.java b/src/org/traccar/geocoder/MapQuestGeocoder.java deleted file mode 100644 index 4029e3f07..000000000 --- a/src/org/traccar/geocoder/MapQuestGeocoder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.geocoder; - -import javax.json.JsonArray; -import javax.json.JsonObject; - -public class MapQuestGeocoder extends JsonGeocoder { - - public MapQuestGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "?key=" + key + "&location=%f,%f", cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("results"); - if (result != null) { - JsonArray locations = result.getJsonObject(0).getJsonArray("locations"); - if (locations != null) { - JsonObject location = locations.getJsonObject(0); - - Address address = new Address(); - - if (location.containsKey("street")) { - address.setStreet(location.getString("street")); - } - if (location.containsKey("adminArea5")) { - address.setSettlement(location.getString("adminArea5")); - } - if (location.containsKey("adminArea4")) { - address.setDistrict(location.getString("adminArea4")); - } - if (location.containsKey("adminArea3")) { - address.setState(location.getString("adminArea3")); - } - if (location.containsKey("adminArea1")) { - address.setCountry(location.getString("adminArea1").toUpperCase()); - } - if (location.containsKey("postalCode")) { - address.setPostcode(location.getString("postalCode")); - } - - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geocoder/MapmyIndiaGeocoder.java b/src/org/traccar/geocoder/MapmyIndiaGeocoder.java deleted file mode 100644 index 2b70708a1..000000000 --- a/src/org/traccar/geocoder/MapmyIndiaGeocoder.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.JsonArray; -import javax.json.JsonObject; - -public class MapmyIndiaGeocoder extends JsonGeocoder { - - public MapmyIndiaGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/" + key + "/rev_geocode?lat=%f&lng=%f", cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray results = json.getJsonArray("results"); - - if (!results.isEmpty()) { - Address address = new Address(); - - JsonObject result = (JsonObject) results.get(0); - - if (result.containsKey("formatted_address")) { - address.setFormattedAddress(result.getString("formatted_address")); - } - - if (result.containsKey("house_number") && !result.getString("house_number").isEmpty()) { - address.setHouse(result.getString("house_number")); - } else if (result.containsKey("house_name") && !result.getString("house_name").isEmpty()) { - address.setHouse(result.getString("house_name")); - } - - if (result.containsKey("street")) { - address.setStreet(result.getString("street")); - } - - if (result.containsKey("locality") && !result.getString("locality").isEmpty()) { - address.setSuburb(result.getString("locality")); - } else if (result.containsKey("sublocality") && !result.getString("sublocality").isEmpty()) { - address.setSuburb(result.getString("sublocality")); - } else if (result.containsKey("subsublocality") && !result.getString("subsublocality").isEmpty()) { - address.setSuburb(result.getString("subsublocality")); - } - - if (result.containsKey("city") && !result.getString("city").isEmpty()) { - address.setSettlement(result.getString("city")); - } else if (result.containsKey("village") && !result.getString("village").isEmpty()) { - address.setSettlement(result.getString("village")); - } - - if (result.containsKey("district")) { - address.setDistrict(result.getString("district")); - } else if (result.containsKey("subDistrict")) { - address.setDistrict(result.getString("subDistrict")); - } - - if (result.containsKey("state")) { - address.setState(result.getString("state")); - } - - if (result.containsKey("pincode")) { - address.setPostcode(result.getString("pincode")); - } - - return address; - } - return null; - } -} diff --git a/src/org/traccar/geocoder/NominatimGeocoder.java b/src/org/traccar/geocoder/NominatimGeocoder.java deleted file mode 100644 index 8db25bf15..000000000 --- a/src/org/traccar/geocoder/NominatimGeocoder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 NominatimGeocoder extends JsonGeocoder { - - private static String formatUrl(String url, String key, String language) { - if (url == null) { - url = "https://nominatim.openstreetmap.org/reverse"; - } - url += "?format=json&lat=%f&lon=%f&zoom=18&addressdetails=1"; - if (key != null) { - url += "&key=" + key; - } - if (language != null) { - url += "&accept-language=" + language; - } - return url; - } - - public NominatimGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key, language), cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonObject result = json.getJsonObject("address"); - - if (result != null) { - Address address = new Address(); - - if (json.containsKey("display_name")) { - address.setFormattedAddress(json.getString("display_name")); - } - - if (result.containsKey("house_number")) { - address.setHouse(result.getString("house_number")); - } - if (result.containsKey("road")) { - address.setStreet(result.getString("road")); - } - if (result.containsKey("suburb")) { - address.setSuburb(result.getString("suburb")); - } - - if (result.containsKey("village")) { - address.setSettlement(result.getString("village")); - } else if (result.containsKey("town")) { - address.setSettlement(result.getString("town")); - } else if (result.containsKey("city")) { - address.setSettlement(result.getString("city")); - } - - if (result.containsKey("state_district")) { - address.setDistrict(result.getString("state_district")); - } else if (result.containsKey("region")) { - address.setDistrict(result.getString("region")); - } - - if (result.containsKey("state")) { - address.setState(result.getString("state")); - } - if (result.containsKey("country_code")) { - address.setCountry(result.getString("country_code").toUpperCase()); - } - if (result.containsKey("postcode")) { - address.setPostcode(result.getString("postcode")); - } - - return address; - } - - return null; - } - -} diff --git a/src/org/traccar/geocoder/OpenCageGeocoder.java b/src/org/traccar/geocoder/OpenCageGeocoder.java deleted file mode 100644 index 822b6e91e..000000000 --- a/src/org/traccar/geocoder/OpenCageGeocoder.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2014 - 2015 Stefaan Van Dooren (stefaan.vandooren@gmail.com) - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.geocoder; - -import javax.json.JsonArray; -import javax.json.JsonObject; - -public class OpenCageGeocoder extends JsonGeocoder { - - public OpenCageGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/json?q=%f,%f&no_annotations=1&key=" + key, cacheSize, addressFormat); - } - - @Override - public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("results"); - if (result != null) { - JsonObject location = result.getJsonObject(0).getJsonObject("components"); - if (location != null) { - Address address = new Address(); - - if (result.getJsonObject(0).containsKey("formatted")) { - address.setFormattedAddress(result.getJsonObject(0).getString("formatted")); - } - if (location.containsKey("building")) { - address.setHouse(location.getString("building")); - } - if (location.containsKey("house_number")) { - address.setHouse(location.getString("house_number")); - } - if (location.containsKey("road")) { - address.setStreet(location.getString("road")); - } - if (location.containsKey("suburb")) { - address.setSuburb(location.getString("suburb")); - } - if (location.containsKey("city")) { - address.setSettlement(location.getString("city")); - } - if (location.containsKey("city_district")) { - address.setSettlement(location.getString("city_district")); - } - if (location.containsKey("county")) { - address.setDistrict(location.getString("county")); - } - if (location.containsKey("state")) { - address.setState(location.getString("state")); - } - if (location.containsKey("country_code")) { - address.setCountry(location.getString("country_code").toUpperCase()); - } - if (location.containsKey("postcode")) { - address.setPostcode(location.getString("postcode")); - } - - return address; - } - } - return null; - } - -} diff --git a/src/org/traccar/geofence/GeofenceCircle.java b/src/org/traccar/geofence/GeofenceCircle.java deleted file mode 100644 index f6fca63ca..000000000 --- a/src/org/traccar/geofence/GeofenceCircle.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.geofence; - -import java.text.DecimalFormat; -import java.text.ParseException; - -import org.traccar.helper.DistanceCalculator; - -public class GeofenceCircle extends GeofenceGeometry { - - private double centerLatitude; - private double centerLongitude; - private double radius; - - public GeofenceCircle() { - } - - public GeofenceCircle(String wkt) throws ParseException { - fromWkt(wkt); - } - - public GeofenceCircle(double latitude, double longitude, double radius) { - this.centerLatitude = latitude; - this.centerLongitude = longitude; - this.radius = radius; - } - - public double distanceFromCenter(double latitude, double longitude) { - return DistanceCalculator.distance(centerLatitude, centerLongitude, latitude, longitude); - } - - @Override - public boolean containsPoint(double latitude, double longitude) { - return distanceFromCenter(latitude, longitude) <= radius; - } - - @Override - public String toWkt() { - String wkt = ""; - wkt = "CIRCLE ("; - wkt += String.valueOf(centerLatitude); - wkt += " "; - wkt += String.valueOf(centerLongitude); - wkt += ", "; - DecimalFormat format = new DecimalFormat("0.#"); - wkt += format.format(radius); - wkt += ")"; - return wkt; - } - - @Override - public void fromWkt(String wkt) throws ParseException { - if (!wkt.startsWith("CIRCLE")) { - throw new ParseException("Mismatch geometry type", 0); - } - String content = wkt.substring(wkt.indexOf("(") + 1, wkt.indexOf(")")); - if (content == null || content.equals("")) { - throw new ParseException("No content", 0); - } - String[] commaTokens = content.split(","); - if (commaTokens.length != 2) { - throw new ParseException("Not valid content", 0); - } - String[] tokens = commaTokens[0].split("\\s"); - if (tokens.length != 2) { - throw new ParseException("Too much or less coordinates", 0); - } - try { - centerLatitude = Double.parseDouble(tokens[0]); - } catch (NumberFormatException e) { - throw new ParseException(tokens[0] + " is not a double", 0); - } - try { - centerLongitude = Double.parseDouble(tokens[1]); - } catch (NumberFormatException e) { - throw new ParseException(tokens[1] + " is not a double", 0); - } - try { - radius = Double.parseDouble(commaTokens[1]); - } catch (NumberFormatException e) { - throw new ParseException(commaTokens[1] + " is not a double", 0); - } - } -} diff --git a/src/org/traccar/geofence/GeofenceGeometry.java b/src/org/traccar/geofence/GeofenceGeometry.java deleted file mode 100644 index 857ba3414..000000000 --- a/src/org/traccar/geofence/GeofenceGeometry.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.geofence; - -import java.text.ParseException; - -public abstract class GeofenceGeometry { - - public abstract boolean containsPoint(double latitude, double longitude); - - public abstract String toWkt(); - - public abstract void fromWkt(String wkt) throws ParseException; - - public static class Coordinate { - - private double lat; - private double lon; - - public double getLat() { - return lat; - } - - public void setLat(double lat) { - this.lat = lat; - } - - public double getLon() { - return lon; - } - - public void setLon(double lon) { - this.lon = lon; - } - } - -} diff --git a/src/org/traccar/geofence/GeofencePolygon.java b/src/org/traccar/geofence/GeofencePolygon.java deleted file mode 100644 index 2048ba26d..000000000 --- a/src/org/traccar/geofence/GeofencePolygon.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.geofence; - -import java.text.ParseException; -import java.util.ArrayList; - -public class GeofencePolygon extends GeofenceGeometry { - - public GeofencePolygon() { - } - - public GeofencePolygon(String wkt) throws ParseException { - fromWkt(wkt); - } - - private ArrayList<Coordinate> coordinates; - - private double[] constant; - private double[] multiple; - - private boolean needNormalize = false; - - private void precalc() { - if (coordinates == null) { - return; - } - - int polyCorners = coordinates.size(); - int i; - int j = polyCorners - 1; - - if (constant != null) { - constant = null; - } - if (multiple != null) { - multiple = null; - } - - constant = new double[polyCorners]; - multiple = new double[polyCorners]; - - boolean hasNegative = false; - boolean hasPositive = false; - for (i = 0; i < polyCorners; i++) { - if (coordinates.get(i).getLon() > 90) { - hasPositive = true; - } else if (coordinates.get(i).getLon() < -90) { - hasNegative = true; - } - } - needNormalize = hasPositive && hasNegative; - - for (i = 0; i < polyCorners; j = i++) { - if (normalizeLon(coordinates.get(j).getLon()) == normalizeLon(coordinates.get(i).getLon())) { - constant[i] = coordinates.get(i).getLat(); - multiple[i] = 0; - } else { - constant[i] = coordinates.get(i).getLat() - - (normalizeLon(coordinates.get(i).getLon()) * coordinates.get(j).getLat()) - / (normalizeLon(coordinates.get(j).getLon()) - normalizeLon(coordinates.get(i).getLon())) - + (normalizeLon(coordinates.get(i).getLon()) * coordinates.get(i).getLat()) - / (normalizeLon(coordinates.get(j).getLon()) - normalizeLon(coordinates.get(i).getLon())); - multiple[i] = (coordinates.get(j).getLat() - coordinates.get(i).getLat()) - / (normalizeLon(coordinates.get(j).getLon()) - normalizeLon(coordinates.get(i).getLon())); - } - } - } - - private double normalizeLon(double lon) { - if (needNormalize && lon < -90) { - return lon + 360; - } - return lon; - } - - @Override - public boolean containsPoint(double latitude, double longitude) { - - int polyCorners = coordinates.size(); - int i; - int j = polyCorners - 1; - double longitudeNorm = normalizeLon(longitude); - boolean oddNodes = false; - - for (i = 0; i < polyCorners; j = i++) { - if (normalizeLon(coordinates.get(i).getLon()) < longitudeNorm - && normalizeLon(coordinates.get(j).getLon()) >= longitudeNorm - || normalizeLon(coordinates.get(j).getLon()) < longitudeNorm - && normalizeLon(coordinates.get(i).getLon()) >= longitudeNorm) { - oddNodes ^= longitudeNorm * multiple[i] + constant[i] < latitude; - } - } - return oddNodes; - } - - @Override - public String toWkt() { - StringBuilder buf = new StringBuilder(); - buf.append("POLYGON (("); - for (Coordinate coordinate : coordinates) { - buf.append(String.valueOf(coordinate.getLat())); - buf.append(" "); - buf.append(String.valueOf(coordinate.getLon())); - buf.append(", "); - } - return buf.substring(0, buf.length() - 2) + "))"; - } - - @Override - public void fromWkt(String wkt) throws ParseException { - if (coordinates == null) { - coordinates = new ArrayList<>(); - } else { - coordinates.clear(); - } - - if (!wkt.startsWith("POLYGON")) { - throw new ParseException("Mismatch geometry type", 0); - } - String content = wkt.substring(wkt.indexOf("((") + 2, wkt.indexOf("))")); - if (content.isEmpty()) { - throw new ParseException("No content", 0); - } - String[] commaTokens = content.split(","); - if (commaTokens.length < 3) { - throw new ParseException("Not valid content", 0); - } - - for (String commaToken : commaTokens) { - String[] tokens = commaToken.trim().split("\\s"); - if (tokens.length != 2) { - throw new ParseException("Here must be two coordinates: " + commaToken, 0); - } - Coordinate coordinate = new Coordinate(); - try { - coordinate.setLat(Double.parseDouble(tokens[0])); - } catch (NumberFormatException e) { - throw new ParseException(tokens[0] + " is not a double", 0); - } - try { - coordinate.setLon(Double.parseDouble(tokens[1])); - } catch (NumberFormatException e) { - throw new ParseException(tokens[1] + " is not a double", 0); - } - coordinates.add(coordinate); - } - precalc(); - } - -} diff --git a/src/org/traccar/geofence/GeofencePolyline.java b/src/org/traccar/geofence/GeofencePolyline.java deleted file mode 100644 index d84f512e3..000000000 --- a/src/org/traccar/geofence/GeofencePolyline.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.geofence; - -import java.text.ParseException; -import java.util.ArrayList; - -import org.traccar.helper.DistanceCalculator; - -public class GeofencePolyline extends GeofenceGeometry { - - private ArrayList<Coordinate> coordinates; - private double distance; - - public GeofencePolyline() { - } - - public GeofencePolyline(String wkt, double distance) throws ParseException { - fromWkt(wkt); - this.distance = distance; - } - - @Override - public boolean containsPoint(double latitude, double longitude) { - for (int i = 1; i < coordinates.size(); i++) { - if (DistanceCalculator.distanceToLine( - latitude, longitude, coordinates.get(i - 1).getLat(), coordinates.get(i - 1).getLon(), - coordinates.get(i).getLat(), coordinates.get(i).getLon()) <= distance) { - return true; - } - } - return false; - } - - @Override - public String toWkt() { - StringBuilder buf = new StringBuilder(); - buf.append("LINESTRING ("); - for (Coordinate coordinate : coordinates) { - buf.append(String.valueOf(coordinate.getLat())); - buf.append(" "); - buf.append(String.valueOf(coordinate.getLon())); - buf.append(", "); - } - return buf.substring(0, buf.length() - 2) + ")"; - } - - @Override - public void fromWkt(String wkt) throws ParseException { - if (coordinates == null) { - coordinates = new ArrayList<>(); - } else { - coordinates.clear(); - } - - if (!wkt.startsWith("LINESTRING")) { - throw new ParseException("Mismatch geometry type", 0); - } - String content = wkt.substring(wkt.indexOf("(") + 1, wkt.indexOf(")")); - if (content.isEmpty()) { - throw new ParseException("No content", 0); - } - String[] commaTokens = content.split(","); - if (commaTokens.length < 2) { - throw new ParseException("Not valid content", 0); - } - - for (String commaToken : commaTokens) { - String[] tokens = commaToken.trim().split("\\s"); - if (tokens.length != 2) { - throw new ParseException("Here must be two coordinates: " + commaToken, 0); - } - Coordinate coordinate = new Coordinate(); - try { - coordinate.setLat(Double.parseDouble(tokens[0])); - } catch (NumberFormatException e) { - throw new ParseException(tokens[0] + " is not a double", 0); - } - try { - coordinate.setLon(Double.parseDouble(tokens[1])); - } catch (NumberFormatException e) { - throw new ParseException(tokens[1] + " is not a double", 0); - } - coordinates.add(coordinate); - } - - } - - public void setDistance(double distance) { - this.distance = distance; - } - -} diff --git a/src/org/traccar/geolocation/GeolocationException.java b/src/org/traccar/geolocation/GeolocationException.java deleted file mode 100644 index 5847cc807..000000000 --- a/src/org/traccar/geolocation/GeolocationException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.geolocation; - -public class GeolocationException extends RuntimeException { - - public GeolocationException(String message) { - super(message); - } - -} diff --git a/src/org/traccar/geolocation/GeolocationProvider.java b/src/org/traccar/geolocation/GeolocationProvider.java deleted file mode 100644 index d9dec6bbb..000000000 --- a/src/org/traccar/geolocation/GeolocationProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.geolocation; - -import org.traccar.model.Network; - -public interface GeolocationProvider { - - interface LocationProviderCallback { - - void onSuccess(double latitude, double longitude, double accuracy); - - void onFailure(Throwable e); - - } - - void getLocation(Network network, LocationProviderCallback callback); - -} diff --git a/src/org/traccar/geolocation/GoogleGeolocationProvider.java b/src/org/traccar/geolocation/GoogleGeolocationProvider.java deleted file mode 100644 index 5901b47cd..000000000 --- a/src/org/traccar/geolocation/GoogleGeolocationProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.geolocation; - -public class GoogleGeolocationProvider extends UniversalGeolocationProvider { - - private static final String URL = "https://www.googleapis.com/geolocation/v1/geolocate"; - - public GoogleGeolocationProvider(String key) { - super(URL, key); - } - -} diff --git a/src/org/traccar/geolocation/MozillaGeolocationProvider.java b/src/org/traccar/geolocation/MozillaGeolocationProvider.java deleted file mode 100644 index c6a73a52b..000000000 --- a/src/org/traccar/geolocation/MozillaGeolocationProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.geolocation; - -public class MozillaGeolocationProvider extends UniversalGeolocationProvider { - - private static final String URL = "https://location.services.mozilla.com/v1/geolocate"; - - public MozillaGeolocationProvider(String key) { - super(URL, key != null ? key : "test"); - } - -} diff --git a/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java deleted file mode 100644 index 768aaf6a2..000000000 --- a/src/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - * 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.geolocation; - -import org.traccar.Context; -import org.traccar.model.CellTower; -import org.traccar.model.Network; - -import javax.json.JsonObject; -import javax.ws.rs.client.InvocationCallback; - -public class OpenCellIdGeolocationProvider implements GeolocationProvider { - - private String url; - - public OpenCellIdGeolocationProvider(String key) { - this("http://opencellid.org/cell/get", key); - } - - public OpenCellIdGeolocationProvider(String url, String key) { - this.url = url + "?format=json&mcc=%d&mnc=%d&lac=%d&cellid=%d&key=" + key; - } - - @Override - public void getLocation(Network network, final LocationProviderCallback callback) { - if (network.getCellTowers() != null && !network.getCellTowers().isEmpty()) { - - CellTower cellTower = network.getCellTowers().iterator().next(); - String request = String.format(url, cellTower.getMobileCountryCode(), cellTower.getMobileNetworkCode(), - cellTower.getLocationAreaCode(), cellTower.getCellId()); - - Context.getClient().target(request).request().async().get(new InvocationCallback<JsonObject>() { - @Override - 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")); - } - } - - @Override - public void failed(Throwable throwable) { - callback.onFailure(throwable); - } - }); - - } else { - callback.onFailure(new GeolocationException("No network information")); - } - } - -} diff --git a/src/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/org/traccar/geolocation/UniversalGeolocationProvider.java deleted file mode 100644 index f71620d8a..000000000 --- a/src/org/traccar/geolocation/UniversalGeolocationProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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.geolocation; - -import org.traccar.Context; -import org.traccar.model.Network; - -import javax.json.JsonObject; -import javax.ws.rs.client.AsyncInvoker; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; - -public class UniversalGeolocationProvider implements GeolocationProvider { - - private String url; - - public UniversalGeolocationProvider(String url, String key) { - this.url = url + "?key=" + key; - } - - @Override - public void getLocation(Network network, final LocationProviderCallback callback) { - 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 failed(Throwable throwable) { - callback.onFailure(throwable); - } - }); - } - -} diff --git a/src/org/traccar/geolocation/UnwiredGeolocationProvider.java b/src/org/traccar/geolocation/UnwiredGeolocationProvider.java deleted file mode 100644 index 963bcb688..000000000 --- a/src/org/traccar/geolocation/UnwiredGeolocationProvider.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - * 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.geolocation; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.traccar.Context; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.WifiAccessPoint; - -import javax.json.JsonObject; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; -import java.util.Collection; - -public class UnwiredGeolocationProvider implements GeolocationProvider { - - private String url; - private String key; - - private ObjectMapper objectMapper; - - private abstract static class NetworkMixIn { - @JsonProperty("mcc") - abstract Integer getHomeMobileCountryCode(); - @JsonProperty("mnc") - abstract Integer getHomeMobileNetworkCode(); - @JsonProperty("radio") - abstract String getRadioType(); - @JsonIgnore - abstract String getCarrier(); - @JsonIgnore - abstract Boolean getConsiderIp(); - @JsonProperty("cells") - abstract Collection<CellTower> getCellTowers(); - @JsonProperty("wifi") - abstract Collection<WifiAccessPoint> getWifiAccessPoints(); - } - - private abstract static class CellTowerMixIn { - @JsonProperty("radio") - abstract String getRadioType(); - @JsonProperty("mcc") - abstract Integer getMobileCountryCode(); - @JsonProperty("mnc") - abstract Integer getMobileNetworkCode(); - @JsonProperty("lac") - abstract Integer getLocationAreaCode(); - @JsonProperty("cid") - abstract Long getCellId(); - } - - private abstract static class WifiAccessPointMixIn { - @JsonProperty("bssid") - abstract String getMacAddress(); - @JsonProperty("signal") - abstract Integer getSignalStrength(); - } - - public UnwiredGeolocationProvider(String url, String key) { - this.url = url; - this.key = key; - - objectMapper = new ObjectMapper(); - objectMapper.addMixIn(Network.class, NetworkMixIn.class); - objectMapper.addMixIn(CellTower.class, CellTowerMixIn.class); - objectMapper.addMixIn(WifiAccessPoint.class, WifiAccessPointMixIn.class); - } - - @Override - public void getLocation(Network network, final LocationProviderCallback callback) { - ObjectNode json = objectMapper.valueToTree(network); - json.put("token", key); - - 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()); - } - } - - @Override - public void failed(Throwable throwable) { - callback.onFailure(throwable); - } - }); - } - -} diff --git a/src/org/traccar/handler/ComputedAttributesHandler.java b/src/org/traccar/handler/ComputedAttributesHandler.java deleted file mode 100644 index 153da29b9..000000000 --- a/src/org/traccar/handler/ComputedAttributesHandler.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.handler; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -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; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseDataHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Attribute; -import org.traccar.model.Device; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class ComputedAttributesHandler extends BaseDataHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class); - - private final IdentityManager identityManager; - private final AttributesManager attributesManager; - - private final JexlEngine engine; - - private final boolean includeDeviceAttributes; - - public ComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { - this.identityManager = identityManager; - this.attributesManager = attributesManager; - engine = new JexlEngine(); - engine.setStrict(true); - engine.setFunctions(Collections.singletonMap("math", Math.class)); - includeDeviceAttributes = config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES); - } - - private MapContext prepareContext(Position position) { - MapContext result = new MapContext(); - if (includeDeviceAttributes) { - Device device = identityManager.getById(position.getDeviceId()); - if (device != null) { - for (Object key : device.getAttributes().keySet()) { - result.set((String) key, device.getAttributes().get(key)); - } - } - } - Set<Method> methods = new HashSet<>(Arrays.asList(position.getClass().getMethods())); - methods.removeAll(Arrays.asList(Object.class.getMethods())); - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { - String name = Character.toLowerCase(method.getName().charAt(3)) + method.getName().substring(4); - - try { - if (!method.getReturnType().equals(Map.class)) { - result.set(name, method.invoke(position)); - } else { - for (Object key : ((Map) method.invoke(position)).keySet()) { - result.set((String) key, ((Map) method.invoke(position)).get(key)); - } - } - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Attribute reflection error", error); - } - } - } - return result; - } - - /** - * @deprecated logic needs to be extracted to be used in API resource - */ - @Deprecated - public Object computeAttribute(Attribute attribute, Position position) throws JexlException { - return engine.createExpression(attribute.getExpression()).evaluate(prepareContext(position)); - } - - @Override - protected Position handlePosition(Position position) { - Collection<Attribute> attributes = attributesManager.getItems( - attributesManager.getAllDeviceItems(position.getDeviceId())); - for (Attribute attribute : attributes) { - if (attribute.getAttribute() != null) { - Object result = null; - try { - result = computeAttribute(attribute, position); - } catch (JexlException error) { - LOGGER.warn("Attribute computation error", error); - } - if (result != null) { - try { - switch (attribute.getType()) { - case "number": - Number numberValue = (Number) result; - position.getAttributes().put(attribute.getAttribute(), numberValue); - break; - case "boolean": - Boolean booleanValue = (Boolean) result; - position.getAttributes().put(attribute.getAttribute(), booleanValue); - break; - default: - position.getAttributes().put(attribute.getAttribute(), result.toString()); - } - } catch (ClassCastException error) { - LOGGER.warn("Attribute cast error", error); - } - } - } - } - return position; - } - -} diff --git a/src/org/traccar/handler/CopyAttributesHandler.java b/src/org/traccar/handler/CopyAttributesHandler.java deleted file mode 100644 index 6a0966d33..000000000 --- a/src/org/traccar/handler/CopyAttributesHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.handler; - -import io.netty.channel.ChannelHandler; -import org.traccar.BaseDataHandler; -import org.traccar.database.IdentityManager; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class CopyAttributesHandler extends BaseDataHandler { - - private IdentityManager identityManager; - - public CopyAttributesHandler(IdentityManager identityManager) { - this.identityManager = identityManager; - } - - @Override - protected Position handlePosition(Position position) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", true); - if (attributesString.isEmpty()) { - attributesString = Position.KEY_DRIVER_UNIQUE_ID; - } else { - attributesString += "," + Position.KEY_DRIVER_UNIQUE_ID; - } - Position last = identityManager.getLastPosition(position.getDeviceId()); - if (last != null) { - for (String attribute : attributesString.split("[ ,]")) { - if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { - position.getAttributes().put(attribute, last.getAttributes().get(attribute)); - } - } - } - return position; - } - -} diff --git a/src/org/traccar/handler/DefaultDataHandler.java b/src/org/traccar/handler/DefaultDataHandler.java deleted file mode 100644 index 9d8ea044d..000000000 --- a/src/org/traccar/handler/DefaultDataHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.handler; - -import io.netty.channel.ChannelHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseDataHandler; -import org.traccar.database.DataManager; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class DefaultDataHandler extends BaseDataHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDataHandler.class); - - private final DataManager dataManager; - - public DefaultDataHandler(DataManager dataManager) { - this.dataManager = dataManager; - } - - @Override - protected Position handlePosition(Position position) { - - try { - dataManager.addObject(position); - } catch (Exception error) { - LOGGER.warn("Failed to store position", error); - } - - return position; - } - -} diff --git a/src/org/traccar/handler/DistanceHandler.java b/src/org/traccar/handler/DistanceHandler.java deleted file mode 100644 index a336a884e..000000000 --- a/src/org/traccar/handler/DistanceHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2015 Amila Silva - * Copyright 2016 - 2019 Anton Tananaev (anton@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.handler; - -import io.netty.channel.ChannelHandler; -import org.traccar.BaseDataHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; -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 IdentityManager identityManager; - - private final boolean filter; - private final int coordinatesMinError; - private final int coordinatesMaxError; - - public DistanceHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; - this.filter = config.getBoolean(Keys.COORDINATES_FILTER); - this.coordinatesMinError = config.getInteger(Keys.COORDINATES_MIN_ERROR); - this.coordinatesMaxError = config.getInteger(Keys.COORDINATES_MAX_ERROR); - } - - @Override - protected Position handlePosition(Position position) { - - double distance = 0.0; - if (position.getAttributes().containsKey(Position.KEY_DISTANCE)) { - distance = position.getDouble(Position.KEY_DISTANCE); - } - double totalDistance = 0.0; - - Position last = identityManager != null ? identityManager.getLastPosition(position.getDeviceId()) : null; - if (last != null) { - totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE); - if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) { - distance = DistanceCalculator.distance( - position.getLatitude(), position.getLongitude(), - last.getLatitude(), last.getLongitude()); - distance = BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); - } - if (filter && last.getValid() && last.getLatitude() != 0 && last.getLongitude() != 0) { - boolean satisfiesMin = coordinatesMinError == 0 || distance > coordinatesMinError; - boolean satisfiesMax = coordinatesMaxError == 0 - || distance < coordinatesMaxError || position.getValid(); - if (!satisfiesMin || !satisfiesMax) { - position.setLatitude(last.getLatitude()); - position.setLongitude(last.getLongitude()); - distance = 0; - } - } - } - position.set(Position.KEY_DISTANCE, distance); - totalDistance = BigDecimal.valueOf(totalDistance + distance).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); - position.set(Position.KEY_TOTAL_DISTANCE, totalDistance); - - return position; - } - -} diff --git a/src/org/traccar/handler/EngineHoursHandler.java b/src/org/traccar/handler/EngineHoursHandler.java deleted file mode 100644 index 92da84e6b..000000000 --- a/src/org/traccar/handler/EngineHoursHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2018 - 2019 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.handler; - -import io.netty.channel.ChannelHandler; -import org.traccar.BaseDataHandler; -import org.traccar.database.IdentityManager; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class EngineHoursHandler extends BaseDataHandler { - - private final IdentityManager identityManager; - - public EngineHoursHandler(IdentityManager identityManager) { - this.identityManager = identityManager; - } - - @Override - protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { - Position last = identityManager.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/handler/FilterHandler.java b/src/org/traccar/handler/FilterHandler.java deleted file mode 100644 index dceaede01..000000000 --- a/src/org/traccar/handler/FilterHandler.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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. - * 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.handler; - -import io.netty.channel.ChannelHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseDataHandler; -import org.traccar.Context; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class FilterHandler extends BaseDataHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(FilterHandler.class); - - private boolean filterInvalid; - private boolean filterZero; - private boolean filterDuplicate; - private long filterFuture; - private boolean filterApproximate; - private int filterAccuracy; - private boolean filterStatic; - private int filterDistance; - private int filterMaxSpeed; - private long filterMinPeriod; - private long skipLimit; - private boolean skipAttributes; - - public FilterHandler(Config config) { - filterInvalid = config.getBoolean(Keys.FILTER_INVALID); - filterZero = config.getBoolean(Keys.FILTER_ZERO); - filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); - filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000; - filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY); - filterApproximate = config.getBoolean(Keys.FILTER_APPROXIMATE); - filterStatic = config.getBoolean(Keys.FILTER_STATIC); - filterDistance = config.getInteger(Keys.FILTER_DISTANCE); - filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); - filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000; - skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; - skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); - } - - private boolean filterInvalid(Position position) { - return filterInvalid && (!position.getValid() - || position.getLatitude() > 90 || position.getLongitude() > 180 - || position.getLatitude() < -90 || position.getLongitude() < -180); - } - - private boolean filterZero(Position position) { - return filterZero && position.getLatitude() == 0.0 && position.getLongitude() == 0.0; - } - - private boolean filterDuplicate(Position position, Position last) { - if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { - for (String key : position.getAttributes().keySet()) { - if (!last.getAttributes().containsKey(key)) { - return false; - } - } - return true; - } - return false; - } - - private boolean filterFuture(Position position) { - return filterFuture != 0 && position.getFixTime().getTime() > System.currentTimeMillis() + filterFuture; - } - - private boolean filterAccuracy(Position position) { - return filterAccuracy != 0 && position.getAccuracy() > filterAccuracy; - } - - private boolean filterApproximate(Position position) { - return filterApproximate && position.getBoolean(Position.KEY_APPROXIMATE); - } - - private boolean filterStatic(Position position) { - return filterStatic && position.getSpeed() == 0.0; - } - - private boolean filterDistance(Position position, Position last) { - if (filterDistance != 0 && last != null) { - return position.getDouble(Position.KEY_DISTANCE) < filterDistance; - } - return false; - } - - private boolean filterMaxSpeed(Position position, Position last) { - if (filterMaxSpeed != 0 && last != null) { - double distance = position.getDouble(Position.KEY_DISTANCE); - double time = position.getFixTime().getTime() - last.getFixTime().getTime(); - return UnitsConverter.knotsFromMps(distance / (time / 1000)) > filterMaxSpeed; - } - 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; - } - return false; - } - - private boolean skipAttributes(Position position) { - if (skipAttributes) { - String attributesString = Context.getIdentityManager().lookupAttributeString( - position.getDeviceId(), "filter.skipAttributes", "", true); - for (String attribute : attributesString.split("[ ,]")) { - if (position.getAttributes().containsKey(attribute)) { - return true; - } - } - } - return false; - } - - private boolean filter(Position position) { - - StringBuilder filterType = new StringBuilder(); - - Position last = null; - if (Context.getIdentityManager() != null) { - last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - } - - if (filterInvalid(position)) { - filterType.append("Invalid "); - } - if (filterZero(position)) { - filterType.append("Zero "); - } - if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Duplicate "); - } - if (filterFuture(position)) { - filterType.append("Future "); - } - if (filterAccuracy(position)) { - filterType.append("Accuracy "); - } - if (filterApproximate(position)) { - filterType.append("Approximate "); - } - if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Static "); - } - if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Distance "); - } - if (filterMaxSpeed(position, last)) { - filterType.append("MaxSpeed "); - } - if (filterMinPeriod(position, last)) { - filterType.append("MinPeriod "); - } - - if (filterType.length() > 0) { - - StringBuilder message = new StringBuilder(); - message.append("Position filtered by "); - message.append(filterType.toString()); - message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); - - LOGGER.info(message.toString()); - return true; - } - - return false; - } - - @Override - protected Position handlePosition(Position position) { - if (filter(position)) { - return null; - } - return position; - } - -} diff --git a/src/org/traccar/handler/GeocoderHandler.java b/src/org/traccar/handler/GeocoderHandler.java deleted file mode 100644 index b96f01b3a..000000000 --- a/src/org/traccar/handler/GeocoderHandler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.handler; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; -import org.traccar.database.StatisticsManager; -import org.traccar.geocoder.Geocoder; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class GeocoderHandler extends ChannelInboundHandlerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(GeocoderHandler.class); - - private final Geocoder geocoder; - private final IdentityManager identityManager; - private final StatisticsManager statisticsManager; - private final boolean ignorePositions; - private final boolean processInvalidPositions; - private final int geocoderReuseDistance; - - public GeocoderHandler( - Config config, Geocoder geocoder, IdentityManager identityManager, StatisticsManager statisticsManager) { - this.geocoder = geocoder; - this.identityManager = identityManager; - this.statisticsManager = statisticsManager; - ignorePositions = Context.getConfig().getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); - processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); - geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, Object message) { - if (message instanceof Position && !ignorePositions) { - final Position position = (Position) message; - if (processInvalidPositions || position.getValid()) { - if (geocoderReuseDistance != 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition != null && lastPosition.getAddress() != null - && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { - position.setAddress(lastPosition.getAddress()); - ctx.fireChannelRead(position); - return; - } - } - - if (statisticsManager != null) { - statisticsManager.registerGeocoderRequest(); - } - - geocoder.getAddress(position.getLatitude(), position.getLongitude(), - new Geocoder.ReverseGeocoderCallback() { - @Override - public void onSuccess(String address) { - position.setAddress(address); - ctx.fireChannelRead(position); - } - - @Override - public void onFailure(Throwable e) { - LOGGER.warn("Geocoding failed", e); - ctx.fireChannelRead(position); - } - }); - } else { - ctx.fireChannelRead(position); - } - } else { - ctx.fireChannelRead(message); - } - } - -} diff --git a/src/org/traccar/handler/GeolocationHandler.java b/src/org/traccar/handler/GeolocationHandler.java deleted file mode 100644 index c7b39e491..000000000 --- a/src/org/traccar/handler/GeolocationHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - * 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.handler; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.StatisticsManager; -import org.traccar.geolocation.GeolocationProvider; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class GeolocationHandler extends ChannelInboundHandlerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class); - - private final GeolocationProvider geolocationProvider; - private final StatisticsManager statisticsManager; - private final boolean processInvalidPositions; - - public GeolocationHandler( - Config config, GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { - this.geolocationProvider = geolocationProvider; - this.statisticsManager = statisticsManager; - this.processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, Object message) { - if (message instanceof Position) { - final Position position = (Position) message; - if ((position.getOutdated() || processInvalidPositions && !position.getValid()) - && position.getNetwork() != null) { - if (statisticsManager != null) { - statisticsManager.registerGeolocationRequest(); - } - - geolocationProvider.getLocation(position.getNetwork(), - new GeolocationProvider.LocationProviderCallback() { - @Override - public void onSuccess(double latitude, double longitude, double accuracy) { - position.set(Position.KEY_APPROXIMATE, true); - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAccuracy(accuracy); - position.setAltitude(0); - position.setSpeed(0); - position.setCourse(0); - position.set(Position.KEY_RSSI, 0); - ctx.fireChannelRead(position); - } - - @Override - public void onFailure(Throwable e) { - LOGGER.warn("Geolocation network error", e); - ctx.fireChannelRead(position); - } - }); - } else { - ctx.fireChannelRead(position); - } - } else { - ctx.fireChannelRead(message); - } - } - -} diff --git a/src/org/traccar/handler/HemisphereHandler.java b/src/org/traccar/handler/HemisphereHandler.java deleted file mode 100644 index aff3d8a64..000000000 --- a/src/org/traccar/handler/HemisphereHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.handler; - -import io.netty.channel.ChannelHandler; -import org.traccar.BaseDataHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class HemisphereHandler extends BaseDataHandler { - - private int latitudeFactor; - private int longitudeFactor; - - public HemisphereHandler(Config config) { - String latitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); - if (latitudeHemisphere != null) { - if (latitudeHemisphere.equalsIgnoreCase("N")) { - latitudeFactor = 1; - } else if (latitudeHemisphere.equalsIgnoreCase("S")) { - latitudeFactor = -1; - } - } - String longitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); - if (longitudeHemisphere != null) { - if (longitudeHemisphere.equalsIgnoreCase("E")) { - longitudeFactor = 1; - } else if (longitudeHemisphere.equalsIgnoreCase("W")) { - longitudeFactor = -1; - } - } - } - - @Override - protected Position handlePosition(Position position) { - if (latitudeFactor != 0) { - position.setLatitude(Math.abs(position.getLatitude()) * latitudeFactor); - } - if (longitudeFactor != 0) { - position.setLongitude(Math.abs(position.getLongitude()) * longitudeFactor); - } - return position; - } - -} diff --git a/src/org/traccar/handler/MotionHandler.java b/src/org/traccar/handler/MotionHandler.java deleted file mode 100644 index e8051dd75..000000000 --- a/src/org/traccar/handler/MotionHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.handler; - -import io.netty.channel.ChannelHandler; -import org.traccar.BaseDataHandler; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class MotionHandler extends BaseDataHandler { - - private double speedThreshold; - - public MotionHandler(double speedThreshold) { - this.speedThreshold = speedThreshold; - } - - @Override - protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_MOTION)) { - position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); - } - return position; - } - -} diff --git a/src/org/traccar/handler/NetworkMessageHandler.java b/src/org/traccar/handler/NetworkMessageHandler.java deleted file mode 100644 index b1d926bfa..000000000 --- a/src/org/traccar/handler/NetworkMessageHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.handler; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.channel.socket.DatagramChannel; -import io.netty.channel.socket.DatagramPacket; -import org.traccar.NetworkMessage; - -import java.net.InetSocketAddress; - -public class NetworkMessageHandler extends ChannelDuplexHandler { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) { - if (ctx.channel() instanceof DatagramChannel) { - DatagramPacket packet = (DatagramPacket) msg; - ctx.fireChannelRead(new NetworkMessage(packet.content(), packet.sender())); - } else if (msg instanceof ByteBuf) { - ByteBuf buffer = (ByteBuf) msg; - ctx.fireChannelRead(new NetworkMessage(buffer, ctx.channel().remoteAddress())); - } - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { - if (msg instanceof NetworkMessage) { - 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); - } - } else { - ctx.write(msg, promise); - } - } - -} diff --git a/src/org/traccar/handler/OpenChannelHandler.java b/src/org/traccar/handler/OpenChannelHandler.java deleted file mode 100644 index d09d617ab..000000000 --- a/src/org/traccar/handler/OpenChannelHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.handler; - -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import org.traccar.TrackerServer; - -public class OpenChannelHandler extends ChannelDuplexHandler { - - private final TrackerServer server; - - public OpenChannelHandler(TrackerServer server) { - this.server = server; - } - - @Override - 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()); - } - -} diff --git a/src/org/traccar/handler/RemoteAddressHandler.java b/src/org/traccar/handler/RemoteAddressHandler.java deleted file mode 100644 index c09b8c39a..000000000 --- a/src/org/traccar/handler/RemoteAddressHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 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.handler; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import org.traccar.model.Position; - -import java.net.InetSocketAddress; - -@ChannelHandler.Sharable -public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) { - - 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); - } - - ctx.fireChannelRead(msg); - } - -} diff --git a/src/org/traccar/handler/StandardLoggingHandler.java b/src/org/traccar/handler/StandardLoggingHandler.java deleted file mode 100644 index 88010458f..000000000 --- a/src/org/traccar/handler/StandardLoggingHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.handler; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.NetworkMessage; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -public class StandardLoggingHandler extends ChannelDuplexHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(StandardLoggingHandler.class); - - @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); - } - - public void log(ChannelHandlerContext ctx, boolean downstream, Object o) { - if (o instanceof NetworkMessage) { - NetworkMessage networkMessage = (NetworkMessage) o; - if (networkMessage.getMessage() instanceof ByteBuf) { - log(ctx, downstream, networkMessage.getRemoteAddress(), (ByteBuf) networkMessage.getMessage()); - } - } else if (o instanceof ByteBuf) { - log(ctx, downstream, ctx.channel().remoteAddress(), (ByteBuf) o); - } - } - - public void log(ChannelHandlerContext ctx, boolean downstream, SocketAddress remoteAddress, ByteBuf buf) { - 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 (remoteAddress instanceof InetSocketAddress) { - message.append(((InetSocketAddress) remoteAddress).getHostString()); - } else { - message.append("unknown"); - } - message.append("]"); - - message.append(" HEX: "); - message.append(ByteBufUtil.hexDump(buf)); - - LOGGER.info(message.toString()); - } - -} diff --git a/src/org/traccar/handler/events/AlertEventHandler.java b/src/org/traccar/handler/events/AlertEventHandler.java deleted file mode 100644 index 0b7c8d23e..000000000 --- a/src/org/traccar/handler/events/AlertEventHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; -import org.traccar.model.Event; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class AlertEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - private final boolean ignoreDuplicateAlerts; - - public AlertEventHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; - ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - Object alarm = position.getAttributes().get(Position.KEY_ALARM); - if (alarm != null) { - boolean ignoreAlert = false; - if (ignoreDuplicateAlerts) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) { - ignoreAlert = true; - } - } - if (!ignoreAlert) { - Event event = new Event(Event.TYPE_ALARM, position.getDeviceId(), position.getId()); - event.set(Position.KEY_ALARM, (String) alarm); - return Collections.singletonMap(event, position); - } - } - return null; - } - -} diff --git a/src/org/traccar/handler/events/BaseEventHandler.java b/src/org/traccar/handler/events/BaseEventHandler.java deleted file mode 100644 index 41f677f6c..000000000 --- a/src/org/traccar/handler/events/BaseEventHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.handler.events; - -import java.util.Map; - -import org.traccar.BaseDataHandler; -import org.traccar.Context; -import org.traccar.model.Event; -import org.traccar.model.Position; - -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); - } - return position; - } - - protected abstract Map<Event, Position> analyzePosition(Position position); - -} diff --git a/src/org/traccar/handler/events/CommandResultEventHandler.java b/src/org/traccar/handler/events/CommandResultEventHandler.java deleted file mode 100644 index cfe676653..000000000 --- a/src/org/traccar/handler/events/CommandResultEventHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.model.Event; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class CommandResultEventHandler extends BaseEventHandler { - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - Object commandResult = position.getAttributes().get(Position.KEY_RESULT); - if (commandResult != null) { - Event event = new Event(Event.TYPE_COMMAND_RESULT, position.getDeviceId(), position.getId()); - event.set(Position.KEY_RESULT, (String) commandResult); - return Collections.singletonMap(event, position); - } - return null; - } - -} diff --git a/src/org/traccar/handler/events/DriverEventHandler.java b/src/org/traccar/handler/events/DriverEventHandler.java deleted file mode 100644 index 994df93fa..000000000 --- a/src/org/traccar/handler/events/DriverEventHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.model.Event; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class DriverEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - - public DriverEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - if (!identityManager.isLatestPosition(position)) { - return null; - } - String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID); - if (driverUniqueId != null) { - String oldDriverUniqueId = null; - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } - if (!driverUniqueId.equals(oldDriverUniqueId)) { - Event event = new Event(Event.TYPE_DRIVER_CHANGED, position.getDeviceId(), position.getId()); - event.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId); - return Collections.singletonMap(event, position); - } - } - return null; - } - -} diff --git a/src/org/traccar/handler/events/FuelDropEventHandler.java b/src/org/traccar/handler/events/FuelDropEventHandler.java deleted file mode 100644 index 59de61bba..000000000 --- a/src/org/traccar/handler/events/FuelDropEventHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@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.handler.events; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Event; -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"; - - private final IdentityManager identityManager; - - public FuelDropEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - - Device device = identityManager.getById(position.getDeviceId()); - if (device == null) { - return null; - } - if (!identityManager.isLatestPosition(position)) { - return null; - } - - double fuelDropThreshold = identityManager - .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, false); - - if (fuelDropThreshold > 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) { - - double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - - position.getDouble(Position.KEY_FUEL_LEVEL); - if (drop >= fuelDropThreshold) { - Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position.getDeviceId(), position.getId()); - event.set(ATTRIBUTE_FUEL_DROP_THRESHOLD, fuelDropThreshold); - return Collections.singletonMap(event, position); - } - } - } - - return null; - } - -} diff --git a/src/org/traccar/handler/events/GeofenceEventHandler.java b/src/org/traccar/handler/events/GeofenceEventHandler.java deleted file mode 100644 index 067c97957..000000000 --- a/src/org/traccar/handler/events/GeofenceEventHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.handler.events; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.CalendarManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Calendar; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class GeofenceEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - private final GeofenceManager geofenceManager; - private final CalendarManager calendarManager; - - public GeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { - this.identityManager = identityManager; - this.geofenceManager = geofenceManager; - this.calendarManager = calendarManager; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); - if (device == null) { - return null; - } - if (!identityManager.isLatestPosition(position) || !position.getValid()) { - return null; - } - - List<Long> currentGeofences = geofenceManager.getCurrentDeviceGeofences(position); - List<Long> oldGeofences = new ArrayList<>(); - if (device.getGeofenceIds() != null) { - oldGeofences.addAll(device.getGeofenceIds()); - } - List<Long> newGeofences = new ArrayList<>(currentGeofences); - newGeofences.removeAll(oldGeofences); - oldGeofences.removeAll(currentGeofences); - - device.setGeofenceIds(currentGeofences); - - Map<Event, Position> events = new HashMap<>(); - for (long geofenceId : oldGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; - if (calendar == null || calendar.checkMoment(position.getFixTime())) { - Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId()); - event.setGeofenceId(geofenceId); - events.put(event, position); - } - } - for (long geofenceId : newGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; - if (calendar == null || calendar.checkMoment(position.getFixTime())) { - Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId()); - event.setGeofenceId(geofenceId); - events.put(event, position); - } - } - return events; - } - -} diff --git a/src/org/traccar/handler/events/IgnitionEventHandler.java b/src/org/traccar/handler/events/IgnitionEventHandler.java deleted file mode 100644 index ec133bafc..000000000 --- a/src/org/traccar/handler/events/IgnitionEventHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class IgnitionEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - - public IgnitionEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); - if (device == null || !identityManager.isLatestPosition(position)) { - return null; - } - - Map<Event, Position> result = null; - - if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { - boolean ignition = position.getBoolean(Position.KEY_IGNITION); - - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) { - boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); - - if (ignition && !oldIgnition) { - result = Collections.singletonMap( - new Event(Event.TYPE_IGNITION_ON, position.getDeviceId(), position.getId()), position); - } else if (!ignition && oldIgnition) { - result = Collections.singletonMap( - new Event(Event.TYPE_IGNITION_OFF, position.getDeviceId(), position.getId()), position); - } - } - } - return result; - } - -} diff --git a/src/org/traccar/handler/events/MaintenanceEventHandler.java b/src/org/traccar/handler/events/MaintenanceEventHandler.java deleted file mode 100644 index 93ae74142..000000000 --- a/src/org/traccar/handler/events/MaintenanceEventHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * 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.handler.events; - -import java.util.HashMap; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; -import org.traccar.model.Event; -import org.traccar.model.Maintenance; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class MaintenanceEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - private final MaintenancesManager maintenancesManager; - - public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { - this.identityManager = identityManager; - this.maintenancesManager = maintenancesManager; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - if (identityManager.getById(position.getDeviceId()) == null - || !identityManager.isLatestPosition(position)) { - return null; - } - - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition == null) { - return null; - } - - Map<Event, Position> events = new HashMap<>(); - for (long maintenanceId : maintenancesManager.getAllDeviceItems(position.getDeviceId())) { - Maintenance maintenance = maintenancesManager.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 events; - } - -} diff --git a/src/org/traccar/handler/events/MotionEventHandler.java b/src/org/traccar/handler/events/MotionEventHandler.java deleted file mode 100644 index 9ec02ccfb..000000000 --- a/src/org/traccar/handler/events/MotionEventHandler.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.ReportUtils; -import org.traccar.reports.model.TripsConfig; - -@ChannelHandler.Sharable -public class MotionEventHandler extends BaseEventHandler { - - private final IdentityManager identityManager; - private final DeviceManager deviceManager; - private final TripsConfig tripsConfig; - - public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - this.identityManager = identityManager; - this.deviceManager = deviceManager; - this.tripsConfig = tripsConfig; - } - - private Map<Event, Position> newEvent(DeviceState deviceState, boolean newMotion) { - String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Position position = deviceState.getMotionPosition(); - Event event = new Event(eventType, position.getDeviceId(), position.getId()); - deviceState.setMotionState(newMotion); - deviceState.setMotionPosition(null); - return Collections.singletonMap(event, position); - } - - public Map<Event, Position> updateMotionState(DeviceState deviceState) { - Map<Event, Position> result = null; - if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { - boolean newMotion = !deviceState.getMotionState(); - Position motionPosition = deviceState.getMotionPosition(); - long currentTime = System.currentTimeMillis(); - long motionTime = motionPosition.getFixTime().getTime() - + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); - if (motionTime <= currentTime) { - result = newEvent(deviceState, newMotion); - } - } - return result; - } - - public Map<Event, Position> updateMotionState(DeviceState deviceState, Position position) { - return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - } - - public Map<Event, Position> updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { - Map<Event, Position> result = null; - Boolean oldMotion = deviceState.getMotionState(); - - long currentTime = position.getFixTime().getTime(); - if (newMotion != oldMotion) { - if (deviceState.getMotionPosition() == null) { - deviceState.setMotionPosition(position); - } - } else { - deviceState.setMotionPosition(null); - } - - Position motionPosition = deviceState.getMotionPosition(); - if (motionPosition != null) { - long motionTime = motionPosition.getFixTime().getTime(); - double distance = ReportUtils.calculateDistance(motionPosition, position, false); - Boolean ignition = null; - if (tripsConfig.getUseIgnition() - && position.getAttributes().containsKey(Position.KEY_IGNITION)) { - ignition = position.getBoolean(Position.KEY_IGNITION); - } - if (newMotion) { - if (motionTime + tripsConfig.getMinimalTripDuration() <= currentTime - || distance >= tripsConfig.getMinimalTripDistance()) { - result = newEvent(deviceState, newMotion); - } - } else { - if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime - || ignition != null && !ignition) { - result = newEvent(deviceState, newMotion); - } - } - } - return result; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - - long deviceId = position.getDeviceId(); - Device device = identityManager.getById(deviceId); - if (device == null) { - return null; - } - if (!identityManager.isLatestPosition(position) - || !tripsConfig.getProcessInvalidPositions() && !position.getValid()) { - return null; - } - - Map<Event, Position> result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); - - if (deviceState.getMotionState() == null) { - deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); - } else { - result = updateMotionState(deviceState, position); - } - deviceManager.setDeviceState(deviceId, deviceState); - return result; - } - -} diff --git a/src/org/traccar/handler/events/OverspeedEventHandler.java b/src/org/traccar/handler/events/OverspeedEventHandler.java deleted file mode 100644 index 157bb64e0..000000000 --- a/src/org/traccar/handler/events/OverspeedEventHandler.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2016 - 2019 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.handler.events; - -import java.util.Collections; -import java.util.Map; - -import io.netty.channel.ChannelHandler; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; -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 = "speed"; - public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; - - private final DeviceManager deviceManager; - private final GeofenceManager geofenceManager; - - private final boolean notRepeat; - private final long minimalDuration; - private final boolean preferLowest; - - public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { - this.deviceManager = deviceManager; - this.geofenceManager = geofenceManager; - notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); - minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; - preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); - } - - private Map<Event, Position> newEvent(DeviceState deviceState, double speedLimit) { - Position position = deviceState.getOverspeedPosition(); - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); - event.set(ATTRIBUTE_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); - } - - public Map<Event, Position> updateOverspeedState(DeviceState deviceState, double speedLimit) { - Map<Event, Position> result = null; - if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() - && deviceState.getOverspeedPosition() != null && speedLimit != 0) { - long currentTime = System.currentTimeMillis(); - Position overspeedPosition = deviceState.getOverspeedPosition(); - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); - } - } - return result; - } - - public Map<Event, Position> updateOverspeedState( - DeviceState deviceState, Position position, double speedLimit, long geofenceId) { - Map<Event, Position> result = null; - - Boolean oldOverspeed = deviceState.getOverspeedState(); - - long currentTime = position.getFixTime().getTime(); - boolean newOverspeed = position.getSpeed() > speedLimit; - 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) { - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (newOverspeed && overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); - } - } - return result; - } - - @Override - protected Map<Event, Position> analyzePosition(Position position) { - - long deviceId = position.getDeviceId(); - Device device = deviceManager.getById(deviceId); - if (device == null) { - return null; - } - if (!deviceManager.isLatestPosition(position) || !position.getValid()) { - return null; - } - - double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); - - double geofenceSpeedLimit = 0; - long overspeedGeofenceId = 0; - - if (geofenceManager != null && device.getGeofenceIds() != null) { - for (long geofenceId : device.getGeofenceIds()) { - Geofence geofence = geofenceManager.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; - } - - Map<Event, Position> result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); - - if (deviceState.getOverspeedState() == null) { - deviceState.setOverspeedState(position.getSpeed() > speedLimit); - deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0); - } else { - result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); - } - - deviceManager.setDeviceState(deviceId, deviceState); - return result; - } - -} diff --git a/src/org/traccar/helper/BcdUtil.java b/src/org/traccar/helper/BcdUtil.java deleted file mode 100644 index c87529e32..000000000 --- a/src/org/traccar/helper/BcdUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.helper; - -import io.netty.buffer.ByteBuf; - -public final class BcdUtil { - - private BcdUtil() { - } - - public static int readInteger(ByteBuf buf, int digits) { - int result = 0; - - for (int i = 0; i < digits / 2; i++) { - int b = buf.readUnsignedByte(); - result *= 10; - result += b >>> 4; - result *= 10; - result += b & 0x0f; - } - - if (digits % 2 != 0) { - int b = buf.getUnsignedByte(buf.readerIndex()); - result *= 10; - result += b >>> 4; - } - - return result; - } - - public static double readCoordinate(ByteBuf buf) { - int b1 = buf.readUnsignedByte(); - int b2 = buf.readUnsignedByte(); - int b3 = buf.readUnsignedByte(); - int b4 = buf.readUnsignedByte(); - - double value = (b2 & 0xf) * 10 + (b3 >> 4); - value += (((b3 & 0xf) * 10 + (b4 >> 4)) * 10 + (b4 & 0xf)) / 1000.0; - value /= 60; - value += ((b1 >> 4 & 0x7) * 10 + (b1 & 0xf)) * 10 + (b2 >> 4); - - if ((b1 & 0x80) != 0) { - value = -value; - } - - return value; - } - -} diff --git a/src/org/traccar/helper/BitBuffer.java b/src/org/traccar/helper/BitBuffer.java deleted file mode 100644 index f30a4557b..000000000 --- a/src/org/traccar/helper/BitBuffer.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - * 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 io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -public class BitBuffer { - - private final ByteBuf buffer; - - private int writeByte; - private int writeCount; - - private int readByte; - private int readCount; - - public BitBuffer() { - buffer = Unpooled.buffer(); - } - - public BitBuffer(ByteBuf buffer) { - this.buffer = buffer; - } - - public void writeEncoded(byte[] bytes) { - for (byte b : bytes) { - b -= 48; - if (b > 40) { - b -= 8; - } - write(b); - } - } - - public void write(int b) { - if (writeCount == 0) { - writeByte |= b; - writeCount = 6; - } else { - int remaining = 8 - writeCount; - writeByte <<= remaining; - writeByte |= b >> (6 - remaining); - buffer.writeByte(writeByte); - writeByte = b & ((1 << (6 - remaining)) - 1); - writeCount = 6 - remaining; - } - } - - public int readUnsigned(int length) { - int result = 0; - - while (length > 0) { - if (readCount == 0) { - readByte = buffer.readUnsignedByte(); - readCount = 8; - } - if (readCount >= length) { - result <<= length; - result |= readByte >> (readCount - length); - readByte &= (1 << (readCount - length)) - 1; - readCount -= length; - length = 0; - } else { - result <<= readCount; - result |= readByte; - length -= readCount; - readByte = 0; - readCount = 0; - } - } - - return result; - } - - public int readSigned(int length) { - int result = readUnsigned(length); - int signBit = 1 << (length - 1); - if ((result & signBit) == 0) { - return result; - } else { - result &= signBit - 1; - result += ~(signBit - 1); - return result; - } - } - -} diff --git a/src/org/traccar/helper/BitUtil.java b/src/org/traccar/helper/BitUtil.java deleted file mode 100644 index b6108edff..000000000 --- a/src/org/traccar/helper/BitUtil.java +++ /dev/null @@ -1,51 +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; - -public final class BitUtil { - - private BitUtil() { - } - - public static boolean check(long number, int index) { - return (number & (1 << index)) != 0; - } - - public static int between(int number, int from, int to) { - return (number >> from) & ((1 << to - from) - 1); - } - - public static int from(int number, int from) { - return number >> from; - } - - public static int to(int number, int to) { - return between(number, 0, to); - } - - public static long between(long number, int from, int to) { - return (number >> from) & ((1L << to - from) - 1L); - } - - public static long from(long number, int from) { - return number >> from; - } - - public static long to(long number, int to) { - return between(number, 0, to); - } - -} diff --git a/src/org/traccar/helper/BufferUtil.java b/src/org/traccar/helper/BufferUtil.java deleted file mode 100644 index 15c619ec5..000000000 --- a/src/org/traccar/helper/BufferUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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) { - ByteBuf wrappedHaystack = Unpooled.wrappedBuffer(haystack); - wrappedHaystack.readerIndex(startIndex - haystack.readerIndex()); - wrappedHaystack.writerIndex(endIndex - haystack.readerIndex()); - int result = indexOf(needle, wrappedHaystack); - return result < 0 ? result : haystack.readerIndex() + result; - } - -} diff --git a/src/org/traccar/helper/Checksum.java b/src/org/traccar/helper/Checksum.java deleted file mode 100644 index adfa697c5..000000000 --- a/src/org/traccar/helper/Checksum.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.helper; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.zip.CRC32; - -public final class Checksum { - - private Checksum() { - } - - 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 result; - } - - public static int crc8(Algorithm algorithm, ByteBuffer buf) { - int crc = algorithm.init; - while (buf.hasRemaining()) { - 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 (crc ^ algorithm.xorOut) & 0xFF; - } - - 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()) { - checksum.update(buf.get()); - } - return (int) checksum.getValue(); - } - - public static int xor(ByteBuffer buf) { - int checksum = 0; - while (buf.hasRemaining()) { - checksum ^= buf.get(); - } - return checksum; - } - - public static int xor(String string) { - byte checksum = 0; - for (byte b : string.getBytes(StandardCharsets.US_ASCII)) { - checksum ^= b; - } - return checksum; - } - - public static String nmea(String msg) { - int checksum = 0; - byte[] bytes = msg.getBytes(StandardCharsets.US_ASCII); - for (int i = 1; i < bytes.length; i++) { - checksum ^= bytes[i]; - } - return String.format("*%02x", checksum).toUpperCase(); - } - - public static int sum(ByteBuffer buf) { - byte checksum = 0; - while (buf.hasRemaining()) { - checksum += buf.get(); - } - return checksum; - } - - public static String sum(String msg) { - byte checksum = 0; - for (byte b : msg.getBytes(StandardCharsets.US_ASCII)) { - checksum += b; - } - return String.format("%02X", checksum).toUpperCase(); - } - - public static long luhn(long imei) { - long checksum = 0; - long remain = imei; - - for (int i = 0; remain != 0; i++) { - long digit = remain % 10; - - if (i % 2 == 0) { - digit *= 2; - if (digit >= 10) { - digit = 1 + (digit % 10); - } - } - - checksum += digit; - remain /= 10; - } - - return (10 - (checksum % 10)) % 10; - } - -} diff --git a/src/org/traccar/helper/DataConverter.java b/src/org/traccar/helper/DataConverter.java deleted file mode 100644 index 7abd4ae93..000000000 --- a/src/org/traccar/helper/DataConverter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.helper; - -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; - -public final class DataConverter { - - private DataConverter() { - } - - public static byte[] parseHex(String string) { - try { - return Hex.decodeHex(string); - } catch (DecoderException e) { - throw new RuntimeException(e); - } - } - - public static String printHex(byte[] data) { - return Hex.encodeHexString(data); - } - - public static byte[] parseBase64(String string) { - return Base64.decodeBase64(string); - } - - public static String printBase64(byte[] data) { - return Base64.encodeBase64String(data); - } - -} diff --git a/src/org/traccar/helper/DateBuilder.java b/src/org/traccar/helper/DateBuilder.java deleted file mode 100644 index 6e1b779f0..000000000 --- a/src/org/traccar/helper/DateBuilder.java +++ /dev/null @@ -1,126 +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 java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -public class DateBuilder { - - private Calendar calendar; - - public DateBuilder() { - this(TimeZone.getTimeZone("UTC")); - } - - public DateBuilder(Date time) { - this(time, TimeZone.getTimeZone("UTC")); - } - - public DateBuilder(TimeZone timeZone) { - this(new Date(0), timeZone); - } - - public DateBuilder(Date time, TimeZone timeZone) { - calendar = Calendar.getInstance(timeZone); - calendar.clear(); - calendar.setTimeInMillis(time.getTime()); - } - - public DateBuilder setYear(int year) { - if (year < 100) { - year += 2000; - } - calendar.set(Calendar.YEAR, year); - return this; - } - - public DateBuilder setMonth(int month) { - calendar.set(Calendar.MONTH, month - 1); - return this; - } - - public DateBuilder setDay(int day) { - calendar.set(Calendar.DAY_OF_MONTH, day); - return this; - } - - public DateBuilder setDate(int year, int month, int day) { - return setYear(year).setMonth(month).setDay(day); - } - - public DateBuilder setDateReverse(int day, int month, int year) { - return setDate(year, month, day); - } - - public DateBuilder setCurrentDate() { - Calendar now = Calendar.getInstance(calendar.getTimeZone()); - return setYear(now.get(Calendar.YEAR)).setMonth(now.get(Calendar.MONTH)).setDay(now.get(Calendar.DAY_OF_MONTH)); - } - - public DateBuilder setHour(int hour) { - calendar.set(Calendar.HOUR_OF_DAY, hour); - return this; - } - - public DateBuilder setMinute(int minute) { - calendar.set(Calendar.MINUTE, minute); - return this; - } - - public DateBuilder addMinute(int minute) { - calendar.add(Calendar.MINUTE, minute); - return this; - } - - public DateBuilder setSecond(int second) { - calendar.set(Calendar.SECOND, second); - return this; - } - - public DateBuilder addSeconds(long seconds) { - calendar.setTimeInMillis(calendar.getTimeInMillis() + seconds * 1000); - return this; - } - - public DateBuilder setMillis(int millis) { - calendar.set(Calendar.MILLISECOND, millis); - return this; - } - - public DateBuilder addMillis(long millis) { - calendar.setTimeInMillis(calendar.getTimeInMillis() + millis); - return this; - } - - public DateBuilder setTime(int hour, int minute, int second) { - return setHour(hour).setMinute(minute).setSecond(second); - } - - public DateBuilder setTimeReverse(int second, int minute, int hour) { - return setHour(hour).setMinute(minute).setSecond(second); - } - - public DateBuilder setTime(int hour, int minute, int second, int millis) { - return setHour(hour).setMinute(minute).setSecond(second).setMillis(millis); - } - - public Date getDate() { - return calendar.getTime(); - } - -} diff --git a/src/org/traccar/helper/DateUtil.java b/src/org/traccar/helper/DateUtil.java deleted file mode 100644 index 20a483e3c..000000000 --- a/src/org/traccar/helper/DateUtil.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.text.SimpleDateFormat; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.Calendar; -import java.util.Date; - -public final class DateUtil { - - private DateUtil() { - } - - public static Date correctDay(Date guess) { - return correctDate(new Date(), guess, Calendar.DAY_OF_MONTH); - } - - public static Date correctYear(Date guess) { - return correctDate(new Date(), guess, Calendar.YEAR); - } - - public static Date correctDate(Date now, Date guess, int field) { - - if (guess.getTime() > now.getTime()) { - Date previous = dateAdd(guess, field, -1); - if (now.getTime() - previous.getTime() < guess.getTime() - now.getTime()) { - return previous; - } - } else if (guess.getTime() < now.getTime()) { - Date next = dateAdd(guess, field, 1); - if (next.getTime() - now.getTime() < now.getTime() - guess.getTime()) { - return next; - } - } - - return guess; - } - - private static Date dateAdd(Date guess, int field, int amount) { - Calendar calendar = Calendar.getInstance(); - calendar.setTime(guess); - calendar.add(field, amount); - return calendar.getTime(); - } - - public static Date parseDate(String value) { - return Date.from(Instant.from(DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(value))); - } - - public static String formatDate(Date date) { - return formatDate(date, true); - } - - public static String formatDate(Date date, boolean zoned) { - if (zoned) { - return DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()).format(date.toInstant()); - } else { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); - } - } - -} diff --git a/src/org/traccar/helper/DistanceCalculator.java b/src/org/traccar/helper/DistanceCalculator.java deleted file mode 100644 index 88d4ef8a4..000000000 --- a/src/org/traccar/helper/DistanceCalculator.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014 - 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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; - -public final class DistanceCalculator { - - private DistanceCalculator() { - } - - private static final double EQUATORIAL_EARTH_RADIUS = 6378.1370; - private static final double DEG_TO_RAD = Math.PI / 180; - - public static double distance(double lat1, double lon1, double lat2, double lon2) { - double dlong = (lon2 - lon1) * DEG_TO_RAD; - double dlat = (lat2 - lat1) * DEG_TO_RAD; - double a = Math.pow(Math.sin(dlat / 2), 2) - + Math.cos(lat1 * DEG_TO_RAD) * Math.cos(lat2 * DEG_TO_RAD) * Math.pow(Math.sin(dlong / 2), 2); - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - double d = EQUATORIAL_EARTH_RADIUS * c; - return d * 1000; - } - - public static double distanceToLine( - double pointLat, double pointLon, double lat1, double lon1, double lat2, double lon2) { - double d0 = distance(pointLat, pointLon, lat1, lon1); - double d1 = distance(lat1, lon1, lat2, lon2); - double d2 = distance(lat2, lon2, pointLat, pointLon); - if (Math.pow(d0, 2) > Math.pow(d1, 2) + Math.pow(d2, 2)) { - return d2; - } - if (Math.pow(d2, 2) > Math.pow(d1, 2) + Math.pow(d0, 2)) { - return d0; - } - double halfP = (d0 + d1 + d2) * 0.5; - double area = Math.sqrt(halfP * (halfP - d0) * (halfP - d1) * (halfP - d2)); - return 2 * area / d1; - } - -} diff --git a/src/org/traccar/helper/Hashing.java b/src/org/traccar/helper/Hashing.java deleted file mode 100644 index e91310eda..000000000 --- a/src/org/traccar/helper/Hashing.java +++ /dev/null @@ -1,100 +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 javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; - -public final class Hashing { - - public static final int ITERATIONS = 1000; - public static final int SALT_SIZE = 24; - public static final int HASH_SIZE = 24; - - private static SecretKeyFactory factory; - static { - try { - factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - } - - public static class HashingResult { - - private final String hash; - private final String salt; - - public HashingResult(String hash, String salt) { - this.hash = hash; - this.salt = salt; - } - - public String getHash() { - return hash; - } - - public String getSalt() { - return salt; - } - } - - private Hashing() { - } - - private static byte[] function(char[] password, byte[] salt) { - try { - PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, HASH_SIZE * Byte.SIZE); - return factory.generateSecret(spec).getEncoded(); - } catch (InvalidKeySpecException e) { - throw new SecurityException(e); - } - } - - private static final SecureRandom RANDOM = new SecureRandom(); - - public static HashingResult createHash(String password) { - byte[] salt = new byte[SALT_SIZE]; - RANDOM.nextBytes(salt); - byte[] hash = function(password.toCharArray(), salt); - return new HashingResult( - DataConverter.printHex(hash), - DataConverter.printHex(salt)); - } - - public static boolean validatePassword(String password, String hashHex, String saltHex) { - byte[] hash = DataConverter.parseHex(hashHex); - byte[] salt = DataConverter.parseHex(saltHex); - return slowEquals(hash, function(password.toCharArray(), salt)); - } - - /** - * Compares two byte arrays in length-constant time. This comparison method - * is used so that password hashes cannot be extracted from an on-line - * system using a timing attack and then attacked off-line. - */ - private static boolean slowEquals(byte[] a, byte[] b) { - int diff = a.length ^ b.length; - for (int i = 0; i < a.length && i < b.length; i++) { - diff |= a[i] ^ b[i]; - } - return diff == 0; - } - -} diff --git a/src/org/traccar/helper/LocationTree.java b/src/org/traccar/helper/LocationTree.java deleted file mode 100644 index 3aff3ce33..000000000 --- a/src/org/traccar/helper/LocationTree.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public class LocationTree { - - public static class Item { - - private Item left, right; - private float x, y; - private String data; - - public Item(float x, float y) { - this(x, y, null); - } - - public Item(float x, float y, String data) { - this.x = x; - this.y = y; - this.data = data; - } - - public String getData() { - return data; - } - - private float squaredDistance(Item item) { - return (x - item.x) * (x - item.x) + (y - item.y) * (y - item.y); - } - - private float axisSquaredDistance(Item item, int axis) { - if (axis == 0) { - return (x - item.x) * (x - item.x); - } else { - return (y - item.y) * (y - item.y); - } - } - - } - - private Item root; - - private ArrayList<Comparator<Item>> comparators = new ArrayList<>(); - - public LocationTree(List<Item> items) { - comparators.add(new Comparator<Item>() { - @Override - public int compare(Item o1, Item o2) { - return Float.compare(o1.x, o2.x); - } - }); - comparators.add(new Comparator<Item>() { - @Override - public int compare(Item o1, Item o2) { - return Float.compare(o1.y, o2.y); - } - }); - root = createTree(items, 0); - } - - private Item createTree(List<Item> items, int depth) { - if (items.isEmpty()) { - return null; - } - Collections.sort(items, comparators.get(depth % 2)); - int currentIndex = items.size() / 2; - Item median = items.get(currentIndex); - median.left = createTree(new ArrayList<>(items.subList(0, currentIndex)), depth + 1); - median.right = createTree(new ArrayList<>(items.subList(currentIndex + 1, items.size())), depth + 1); - return median; - } - - public Item findNearest(Item search) { - return findNearest(root, search, 0); - } - - private Item findNearest(Item current, Item search, int depth) { - int direction = comparators.get(depth % 2).compare(search, current); - - Item next, other; - if (direction < 0) { - next = current.left; - other = current.right; - } else { - next = current.right; - other = current.left; - } - - Item best = current; - if (next != null) { - best = findNearest(next, search, depth + 1); - } - - if (current.squaredDistance(search) < best.squaredDistance(search)) { - best = current; - } - if (other != null && current.axisSquaredDistance(search, depth % 2) < best.squaredDistance(search)) { - Item possibleBest = findNearest(other, search, depth + 1); - if (possibleBest.squaredDistance(search) < best.squaredDistance(search)) { - best = possibleBest; - } - } - - return best; - } - -} diff --git a/src/org/traccar/helper/Log.java b/src/org/traccar/helper/Log.java deleted file mode 100644 index f328e8ce9..000000000 --- a/src/org/traccar/helper/Log.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.traccar.config.Config; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.logging.ConsoleHandler; -import java.util.logging.Formatter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -public final class Log { - - private Log() { - } - - private static final String STACK_PACKAGE = "org.traccar"; - private static final int STACK_LIMIT = 3; - - private static class RollingFileHandler extends Handler { - - private String name; - private String suffix; - private Writer writer; - private boolean rotate; - - RollingFileHandler(String name, boolean rotate) { - this.name = name; - this.rotate = rotate; - } - - @Override - public synchronized void publish(LogRecord record) { - if (isLoggable(record)) { - try { - String suffix = ""; - if (rotate) { - suffix = new SimpleDateFormat("yyyyMMdd").format(new Date(record.getMillis())); - if (writer != null && !suffix.equals(this.suffix)) { - writer.close(); - writer = null; - if (!new File(name).renameTo(new File(name + "." + this.suffix))) { - throw new RuntimeException("Log file renaming failed"); - } - } - } - if (writer == null) { - this.suffix = suffix; - writer = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(name, true), StandardCharsets.UTF_8)); - } - writer.write(getFormatter().format(record)); - writer.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public synchronized void flush() { - if (writer != null) { - try { - writer.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public synchronized void close() throws SecurityException { - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - } - - public static class LogFormatter extends Formatter { - - private boolean fullStackTraces; - - LogFormatter(boolean fullStackTraces) { - this.fullStackTraces = fullStackTraces; - } - - private static String formatLevel(Level level) { - switch (level.getName()) { - case "FINEST": - return "TRACE"; - case "FINER": - case "FINE": - case "CONFIG": - return "DEBUG"; - case "INFO": - return "INFO"; - case "WARNING": - return "WARN"; - case "SEVERE": - default: - return "ERROR"; - } - } - - @Override - public String format(LogRecord record) { - StringBuilder message = new StringBuilder(); - - if (record.getMessage() != null) { - message.append(record.getMessage()); - } - - if (record.getThrown() != null) { - if (message.length() > 0) { - message.append(" - "); - } - if (fullStackTraces) { - StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter(stringWriter); - record.getThrown().printStackTrace(printWriter); - message.append(System.lineSeparator()).append(stringWriter.toString()); - } else { - message.append(exceptionStack(record.getThrown())); - } - } - - return String.format("%1$tF %1$tT %2$5s: %3$s%n", - new Date(record.getMillis()), formatLevel(record.getLevel()), message.toString()); - } - - } - - public static void setupDefaultLogger() { - String path = null; - URL url = ClassLoader.getSystemClassLoader().getResource("."); - if (url != null) { - File jarPath = new File(url.getPath()); - File logsPath = new File(jarPath, "logs"); - if (!logsPath.exists() || !logsPath.isDirectory()) { - logsPath = jarPath; - } - path = new File(logsPath, "tracker-server.log").getPath(); - } - setupLogger(path == null, path, Level.WARNING.getName(), false, true); - } - - public static void setupLogger(Config config) { - setupLogger( - config.getBoolean("logger.console"), - config.getString("logger.file"), - config.getString("logger.level"), - config.getBoolean("logger.fullStackTraces"), - config.getBoolean("logger.rotate")); - } - - private static void setupLogger( - boolean console, String file, String levelString, boolean fullStackTraces, boolean rotate) { - - Logger rootLogger = Logger.getLogger(""); - for (Handler handler : rootLogger.getHandlers()) { - rootLogger.removeHandler(handler); - } - - Handler handler; - if (console) { - handler = new ConsoleHandler(); - } else { - handler = new RollingFileHandler(file, rotate); - } - - handler.setFormatter(new LogFormatter(fullStackTraces)); - - Level level = Level.parse(levelString.toUpperCase()); - rootLogger.setLevel(level); - handler.setLevel(level); - handler.setFilter(record -> record != null && !record.getLoggerName().startsWith("sun")); - - rootLogger.addHandler(handler); - } - - public static String exceptionStack(Throwable exception) { - StringBuilder s = new StringBuilder(); - String exceptionMsg = exception.getMessage(); - if (exceptionMsg != null) { - s.append(exceptionMsg); - s.append(" - "); - } - s.append(exception.getClass().getSimpleName()); - StackTraceElement[] stack = exception.getStackTrace(); - - if (stack.length > 0) { - int count = STACK_LIMIT; - boolean first = true; - boolean skip = false; - String file = ""; - s.append(" ("); - for (StackTraceElement element : stack) { - if (count > 0 && element.getClassName().startsWith(STACK_PACKAGE)) { - if (!first) { - s.append(" < "); - } else { - first = false; - } - - if (skip) { - s.append("... < "); - skip = false; - } - - if (file.equals(element.getFileName())) { - s.append("*"); - } else { - file = element.getFileName(); - s.append(file, 0, file.length() - 5); // remove ".java" - count -= 1; - } - s.append(":").append(element.getLineNumber()); - } else { - skip = true; - } - } - if (skip) { - if (!first) { - s.append(" < "); - } - s.append("..."); - } - s.append(")"); - } - return s.toString(); - } - -} diff --git a/src/org/traccar/helper/LogAction.java b/src/org/traccar/helper/LogAction.java deleted file mode 100644 index db13337b8..000000000 --- a/src/org/traccar/helper/LogAction.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.beans.Introspector; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.BaseModel; - -public final class LogAction { - - private static final Logger LOGGER = LoggerFactory.getLogger(LogAction.class); - - private LogAction() { - } - - private static final String ACTION_CREATE = "create"; - private static final String ACTION_EDIT = "edit"; - private static final String ACTION_REMOVE = "remove"; - - private static final String ACTION_LINK = "link"; - private static final String ACTION_UNLINK = "unlink"; - - private static final String ACTION_LOGIN = "login"; - private static final String ACTION_LOGOUT = "logout"; - - private static final String ACTION_DEVICE_ACCUMULATORS = "resetDeviceAccumulators"; - - private static final String PATTERN_OBJECT = "user: %d, action: %s, object: %s, id: %d"; - private static final String PATTERN_LINK = "user: %d, action: %s, owner: %s, id: %d, property: %s, id: %d"; - private static final String PATTERN_LOGIN = "user: %d, action: %s"; - private static final String PATTERN_DEVICE_ACCUMULATORS = "user: %d, action: %s, deviceId: %d"; - - public static void create(long userId, BaseModel object) { - logObjectAction(ACTION_CREATE, userId, object.getClass(), object.getId()); - } - - public static void edit(long userId, BaseModel object) { - logObjectAction(ACTION_EDIT, userId, object.getClass(), object.getId()); - } - - public static void remove(long userId, Class<?> clazz, long objectId) { - logObjectAction(ACTION_REMOVE, userId, clazz, objectId); - } - - public static void link(long userId, Class<?> owner, long ownerId, Class<?> property, long propertyId) { - logLinkAction(ACTION_LINK, userId, owner, ownerId, property, propertyId); - } - - public static void unlink(long userId, Class<?> owner, long ownerId, Class<?> property, long propertyId) { - logLinkAction(ACTION_UNLINK, userId, owner, ownerId, property, propertyId); - } - - public static void login(long userId) { - logLoginAction(ACTION_LOGIN, userId); - } - - public static void logout(long userId) { - logLoginAction(ACTION_LOGOUT, userId); - } - - public static void resetDeviceAccumulators(long userId, long deviceId) { - LOGGER.info(String.format( - PATTERN_DEVICE_ACCUMULATORS, userId, ACTION_DEVICE_ACCUMULATORS, deviceId)); - } - - private static void logObjectAction(String action, long userId, Class<?> clazz, long objectId) { - LOGGER.info(String.format( - PATTERN_OBJECT, userId, action, Introspector.decapitalize(clazz.getSimpleName()), objectId)); - } - - private static void logLinkAction(String action, long userId, - Class<?> owner, long ownerId, Class<?> property, long propertyId) { - LOGGER.info(String.format( - PATTERN_LINK, userId, action, - Introspector.decapitalize(owner.getSimpleName()), ownerId, - Introspector.decapitalize(property.getSimpleName()), propertyId)); - } - - private static void logLoginAction(String action, long userId) { - LOGGER.info(String.format(PATTERN_LOGIN, userId, action)); - } - -} diff --git a/src/org/traccar/helper/ObdDecoder.java b/src/org/traccar/helper/ObdDecoder.java deleted file mode 100644 index 1bdcce352..000000000 --- a/src/org/traccar/helper/ObdDecoder.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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. - * 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.traccar.model.Position; - -import java.util.AbstractMap; -import java.util.Map; - -public final class ObdDecoder { - - private ObdDecoder() { - } - - private static final int MODE_CURRENT = 0x01; - private static final int MODE_FREEZE_FRAME = 0x02; - private static final int MODE_CODES = 0x03; - - public static Map.Entry<String, Object> decode(int mode, String value) { - switch (mode) { - case MODE_CURRENT: - case MODE_FREEZE_FRAME: - return decodeData( - Integer.parseInt(value.substring(0, 2), 16), - Integer.parseInt(value.substring(2), 16), true); - case MODE_CODES: - return decodeCodes(value); - default: - return null; - } - } - - private static Map.Entry<String, Object> createEntry(String key, Object value) { - return new AbstractMap.SimpleEntry<>(key, value); - } - - public static Map.Entry<String, Object> decodeCodes(String value) { - StringBuilder codes = new StringBuilder(); - for (int i = 0; i < value.length() / 4; i++) { - int numValue = Integer.parseInt(value.substring(i * 4, (i + 1) * 4), 16); - codes.append(' '); - switch (numValue >> 14) { - case 1: - codes.append('C'); - break; - case 2: - codes.append('B'); - break; - case 3: - codes.append('U'); - break; - default: - codes.append('P'); - break; - } - codes.append(String.format("%04X", numValue & 0x3FFF)); - } - if (codes.length() > 0) { - return createEntry(Position.KEY_DTCS, codes.toString().trim()); - } else { - return null; - } - } - - public static Map.Entry<String, Object> decodeData(int pid, int value, boolean convert) { - switch (pid) { - case 0x04: - return createEntry(Position.KEY_ENGINE_LOAD, convert ? value * 100 / 255 : value); - case 0x05: - return createEntry(Position.KEY_COOLANT_TEMP, convert ? value - 40 : value); - case 0x0B: - return createEntry("mapIntake", value); - case 0x0C: - return createEntry(Position.KEY_RPM, convert ? value / 4 : value); - case 0x0D: - return createEntry(Position.KEY_OBD_SPEED, value); - case 0x0F: - return createEntry("intakeTemp", convert ? value - 40 : value); - case 0x11: - return createEntry(Position.KEY_THROTTLE, convert ? value * 100 / 255 : value); - case 0x21: - return createEntry("milDistance", value); - case 0x2F: - return createEntry(Position.KEY_FUEL_LEVEL, convert ? value * 100 / 255 : value); - case 0x31: - return createEntry("clearedDistance", value); - default: - return null; - } - } - -} diff --git a/src/org/traccar/helper/Parser.java b/src/org/traccar/helper/Parser.java deleted file mode 100644 index 1471ec237..000000000 --- a/src/org/traccar/helper/Parser.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.util.Date; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Parser { - - private int position; - private final Matcher matcher; - - public Parser(Pattern pattern, String input) { - matcher = pattern.matcher(input); - } - - public boolean matches() { - position = 1; - return matcher.matches(); - } - - public boolean find() { - position = 1; - return matcher.find(); - } - - public void skip(int number) { - position += number; - } - - public boolean hasNext() { - return hasNext(1); - } - - public boolean hasNext(int number) { - String value = matcher.group(position); - if (value != null && !value.isEmpty()) { - return true; - } else { - position += number; - return false; - } - } - - public String next() { - return matcher.group(position++); - } - - public Integer nextInt() { - if (hasNext()) { - return Integer.parseInt(next()); - } else { - return null; - } - } - - public int nextInt(int defaultValue) { - if (hasNext()) { - return Integer.parseInt(next()); - } else { - return defaultValue; - } - } - - public Integer nextHexInt() { - if (hasNext()) { - return Integer.parseInt(next(), 16); - } else { - return null; - } - } - - public int nextHexInt(int defaultValue) { - if (hasNext()) { - return Integer.parseInt(next(), 16); - } else { - return defaultValue; - } - } - - public Integer nextBinInt() { - if (hasNext()) { - return Integer.parseInt(next(), 2); - } else { - return null; - } - } - - public int nextBinInt(int defaultValue) { - if (hasNext()) { - return Integer.parseInt(next(), 2); - } else { - return defaultValue; - } - } - - public Long nextLong() { - if (hasNext()) { - return Long.parseLong(next()); - } else { - return null; - } - } - - public Long nextHexLong() { - if (hasNext()) { - return Long.parseLong(next(), 16); - } else { - return null; - } - } - - public long nextLong(long defaultValue) { - return nextLong(10, defaultValue); - } - - public long nextLong(int radix, long defaultValue) { - if (hasNext()) { - return Long.parseLong(next(), radix); - } else { - return defaultValue; - } - } - - public Double nextDouble() { - if (hasNext()) { - return Double.parseDouble(next()); - } else { - return null; - } - } - - public double nextDouble(double defaultValue) { - if (hasNext()) { - return Double.parseDouble(next()); - } else { - return defaultValue; - } - } - - public enum CoordinateFormat { - DEG_DEG, - DEG_HEM, - DEG_MIN_MIN, - DEG_MIN_HEM, - DEG_MIN_MIN_HEM, - HEM_DEG_MIN_MIN, - HEM_DEG, - HEM_DEG_MIN, - HEM_DEG_MIN_HEM - } - - public double nextCoordinate(CoordinateFormat format) { - double coordinate; - String hemisphere = null; - - switch (format) { - case DEG_DEG: - coordinate = Double.parseDouble(next() + '.' + next()); - break; - case DEG_HEM: - coordinate = nextDouble(0); - hemisphere = next(); - break; - case DEG_MIN_MIN: - coordinate = nextInt(0); - coordinate += Double.parseDouble(next() + '.' + next()) / 60; - break; - case DEG_MIN_MIN_HEM: - coordinate = nextInt(0); - coordinate += Double.parseDouble(next() + '.' + next()) / 60; - hemisphere = next(); - break; - case HEM_DEG: - hemisphere = next(); - coordinate = nextDouble(0); - break; - case HEM_DEG_MIN: - hemisphere = next(); - coordinate = nextInt(0); - coordinate += nextDouble(0) / 60; - break; - case HEM_DEG_MIN_HEM: - hemisphere = next(); - coordinate = nextInt(0); - coordinate += nextDouble(0) / 60; - if (hasNext()) { - hemisphere = next(); - } - break; - case HEM_DEG_MIN_MIN: - hemisphere = next(); - coordinate = nextInt(0); - coordinate += Double.parseDouble(next() + '.' + next()) / 60; - break; - case DEG_MIN_HEM: - default: - coordinate = nextInt(0); - coordinate += nextDouble(0) / 60; - hemisphere = next(); - break; - } - - if (hemisphere != null && (hemisphere.equals("S") || hemisphere.equals("W") || hemisphere.equals("-"))) { - coordinate = -Math.abs(coordinate); - } - - return coordinate; - } - - public double nextCoordinate() { - return nextCoordinate(CoordinateFormat.DEG_MIN_HEM); - } - - public enum DateTimeFormat { - HMS, - SMH, - HMS_YMD, - HMS_DMY, - SMH_YMD, - SMH_DMY, - DMY_HMS, - DMY_HMSS, - YMD_HMS, - YMD_HMSS, - } - - public Date nextDateTime(DateTimeFormat format, String timeZone) { - int year = 0, month = 0, day = 0; - int hour = 0, minute = 0, second = 0, millisecond = 0; - - switch (format) { - case HMS: - hour = nextInt(0); - minute = nextInt(0); - second = nextInt(0); - break; - case SMH: - second = nextInt(0); - minute = nextInt(0); - hour = nextInt(0); - break; - case HMS_YMD: - hour = nextInt(0); - minute = nextInt(0); - second = nextInt(0); - year = nextInt(0); - month = nextInt(0); - day = nextInt(0); - break; - case HMS_DMY: - hour = nextInt(0); - minute = nextInt(0); - second = nextInt(0); - day = nextInt(0); - month = nextInt(0); - year = nextInt(0); - break; - case SMH_YMD: - second = nextInt(0); - minute = nextInt(0); - hour = nextInt(0); - year = nextInt(0); - month = nextInt(0); - day = nextInt(0); - break; - case SMH_DMY: - second = nextInt(0); - minute = nextInt(0); - hour = nextInt(0); - day = nextInt(0); - month = nextInt(0); - year = nextInt(0); - break; - case DMY_HMS: - case DMY_HMSS: - day = nextInt(0); - month = nextInt(0); - year = nextInt(0); - hour = nextInt(0); - minute = nextInt(0); - second = nextInt(0); - break; - case YMD_HMS: - case YMD_HMSS: - default: - year = nextInt(0); - month = nextInt(0); - day = nextInt(0); - hour = nextInt(0); - minute = nextInt(0); - second = nextInt(0); - break; - } - - if (format == DateTimeFormat.YMD_HMSS || format == DateTimeFormat.DMY_HMSS) { - millisecond = nextInt(0); // (ddd) - } - - if (year >= 0 && year < 100) { - year += 2000; - } - - DateBuilder dateBuilder; - if (format != DateTimeFormat.HMS && format != DateTimeFormat.SMH) { - if (timeZone != null) { - dateBuilder = new DateBuilder(TimeZone.getTimeZone(timeZone)); - } else { - dateBuilder = new DateBuilder(); - } - dateBuilder.setDate(year, month, day); - } else { - if (timeZone != null) { - dateBuilder = new DateBuilder(new Date(), TimeZone.getTimeZone(timeZone)); - } else { - dateBuilder = new DateBuilder(new Date()); - } - } - - dateBuilder.setTime(hour, minute, second, millisecond); - - return dateBuilder.getDate(); - } - - public Date nextDateTime(DateTimeFormat format) { - return nextDateTime(format, null); - } - - public Date nextDateTime() { - return nextDateTime(DateTimeFormat.YMD_HMS, null); - } - -} diff --git a/src/org/traccar/helper/PatternBuilder.java b/src/org/traccar/helper/PatternBuilder.java deleted file mode 100644 index 5c4638189..000000000 --- a/src/org/traccar/helper/PatternBuilder.java +++ /dev/null @@ -1,98 +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 java.util.ArrayList; -import java.util.regex.Pattern; - -public class PatternBuilder { - - private final ArrayList<String> fragments = new ArrayList<>(); - - public PatternBuilder optional() { - return optional(1); - } - - public PatternBuilder optional(int count) { - fragments.add(fragments.size() - count, "(?:"); - fragments.add(")?"); - return this; - } - - public PatternBuilder expression(String s) { - s = s.replaceAll("\\|$", "\\\\|"); // special case for delimiter - - fragments.add(s); - return this; - } - - public PatternBuilder text(String s) { - fragments.add(s.replaceAll("([\\\\\\.\\[\\{\\(\\)\\*\\+\\?\\^\\$\\|])", "\\\\$1")); - return this; - } - - public PatternBuilder number(String s) { - s = s.replace("dddd", "d{4}").replace("ddd", "d{3}").replace("dd", "d{2}"); - s = s.replace("xxxx", "x{4}").replace("xxx", "x{3}").replace("xx", "x{2}"); - - s = s.replace("d", "\\d").replace("x", "[0-9a-fA-F]").replaceAll("([\\.])", "\\\\$1"); - s = s.replaceAll("\\|$", "\\\\|").replaceAll("^\\|", "\\\\|"); // special case for delimiter - - fragments.add(s); - return this; - } - - public PatternBuilder any() { - fragments.add(".*"); - return this; - } - - public PatternBuilder binary(String s) { - fragments.add(s.replaceAll("(\\p{XDigit}{2})", "\\\\$1")); - return this; - } - - public PatternBuilder or() { - fragments.add("|"); - return this; - } - - public PatternBuilder groupBegin() { - return expression("(?:"); - } - - public PatternBuilder groupEnd() { - return expression(")"); - } - - public PatternBuilder groupEnd(String s) { - return expression(")" + s); - } - - public Pattern compile() { - return Pattern.compile(toString(), Pattern.DOTALL); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - for (String fragment : fragments) { - builder.append(fragment); - } - return builder.toString(); - } - -} diff --git a/src/org/traccar/helper/PatternUtil.java b/src/org/traccar/helper/PatternUtil.java deleted file mode 100644 index 74813e1d9..000000000 --- a/src/org/traccar/helper/PatternUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.management.ManagementFactory; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -public final class PatternUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(PatternUtil.class); - - private PatternUtil() { - } - - public static class MatchResult { - private String patternMatch; - private String patternTail; - private String stringMatch; - private String stringTail; - - public String getPatternMatch() { - return patternMatch; - } - - public String getPatternTail() { - return patternTail; - } - - public String getStringMatch() { - return stringMatch; - } - - public String getStringTail() { - return stringTail; - } - } - - public static MatchResult checkPattern(String pattern, String input) { - - if (!ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("-agentlib:jdwp")) { - throw new RuntimeException("PatternUtil usage detected"); - } - - MatchResult result = new MatchResult(); - - for (int i = 0; i < pattern.length(); i++) { - try { - Matcher matcher = Pattern.compile("(" + pattern.substring(0, i) + ").*").matcher(input); - if (matcher.matches()) { - result.patternMatch = pattern.substring(0, i); - result.patternTail = pattern.substring(i); - result.stringMatch = matcher.group(1); - result.stringTail = input.substring(matcher.group(1).length()); - } - } catch (PatternSyntaxException error) { - LOGGER.warn("Pattern matching error", error); - } - } - - return result; - } - -} diff --git a/src/org/traccar/helper/SanitizerModule.java b/src/org/traccar/helper/SanitizerModule.java deleted file mode 100644 index af9ac5c2b..000000000 --- a/src/org/traccar/helper/SanitizerModule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.helper; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import org.owasp.encoder.Encode; - -import java.io.IOException; - -public class SanitizerModule extends SimpleModule { - - public static class SanitizerSerializer extends StdSerializer<String> { - - protected SanitizerSerializer() { - super(String.class); - } - - @Override - public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException { - gen.writeString(Encode.forHtml(value)); - } - - } - - public SanitizerModule() { - addSerializer(new SanitizerSerializer()); - } - -} diff --git a/src/org/traccar/helper/UnitsConverter.java b/src/org/traccar/helper/UnitsConverter.java deleted file mode 100644 index 3dd435df4..000000000 --- a/src/org/traccar/helper/UnitsConverter.java +++ /dev/null @@ -1,88 +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; - -public final class UnitsConverter { - - private static final double KNOTS_TO_KPH_RATIO = 0.539957; - private static final double KNOTS_TO_MPH_RATIO = 0.868976; - private static final double KNOTS_TO_MPS_RATIO = 1.94384; - 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() { - } - - public static double knotsFromKph(double value) { // km/h - return value * KNOTS_TO_KPH_RATIO; - } - - public static double kphFromKnots(double value) { - return value / KNOTS_TO_KPH_RATIO; - } - - public static double knotsFromMph(double value) { - return value * KNOTS_TO_MPH_RATIO; - } - - public static double mphFromKnots(double value) { - return value / KNOTS_TO_MPH_RATIO; - } - - public static double knotsFromMps(double value) { // m/s - return value * KNOTS_TO_MPS_RATIO; - } - - public static double mpsFromKnots(double value) { - return value / KNOTS_TO_MPS_RATIO; - } - - public static double knotsFromCps(double value) { // cm/s - return value * KNOTS_TO_CPS_RATIO; - } - - public static double feetFromMeters(double value) { - return value / METERS_TO_FEET_RATIO; - } - - public static double metersFromFeet(double value) { - return value * METERS_TO_FEET_RATIO; - } - - public static double milesFromMeters(double value) { - return value / METERS_TO_MILE_RATIO; - } - - public static double metersFromMiles(double value) { - 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/Attribute.java b/src/org/traccar/model/Attribute.java deleted file mode 100644 index 45d40b3ec..000000000 --- a/src/org/traccar/model/Attribute.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 Attribute extends BaseModel { - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - private String attribute; - - public String getAttribute() { - return attribute; - } - - public void setAttribute(String attribute) { - this.attribute = attribute; - } - - private String expression; - - public String getExpression() { - return expression; - } - - public void setExpression(String expression) { - this.expression = expression; - } - - private String type; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - -} diff --git a/src/org/traccar/model/BaseModel.java b/src/org/traccar/model/BaseModel.java deleted file mode 100644 index 8bdb916e8..000000000 --- a/src/org/traccar/model/BaseModel.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 BaseModel { - - private long id; - - public final long getId() { - return id; - } - - public final void setId(long id) { - this.id = id; - } - -} diff --git a/src/org/traccar/model/Calendar.java b/src/org/traccar/model/Calendar.java deleted file mode 100644 index 56d3eb74c..000000000 --- a/src/org/traccar/model/Calendar.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.Date; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -import net.fortuna.ical4j.data.CalendarBuilder; -import net.fortuna.ical4j.data.ParserException; -import net.fortuna.ical4j.filter.Filter; -import net.fortuna.ical4j.filter.PeriodRule; -import net.fortuna.ical4j.model.DateTime; -import net.fortuna.ical4j.model.Dur; -import net.fortuna.ical4j.model.Period; -import net.fortuna.ical4j.model.component.CalendarComponent; -import org.apache.commons.collections4.Predicate; -import org.traccar.database.QueryIgnore; - -public class Calendar extends ExtendedModel { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private byte[] data; - - public byte[] getData() { - return data.clone(); - } - - public void setData(byte[] data) throws IOException, ParserException { - CalendarBuilder builder = new CalendarBuilder(); - calendar = builder.build(new ByteArrayInputStream(data)); - this.data = data.clone(); - } - - private net.fortuna.ical4j.model.Calendar calendar; - - @QueryIgnore - @JsonIgnore - public net.fortuna.ical4j.model.Calendar getCalendar() { - return calendar; - } - - public boolean checkMoment(Date date) { - if (calendar != null) { - Period period = new Period(new DateTime(date), new Dur(0, 0, 0, 0)); - Predicate<CalendarComponent> periodRule = new PeriodRule<>(period); - Filter<CalendarComponent> filter = new Filter<>(new Predicate[] {periodRule}, Filter.MATCH_ANY); - Collection<CalendarComponent> events = filter.filter(calendar.getComponents(CalendarComponent.VEVENT)); - if (events != null && !events.isEmpty()) { - return true; - } - } - return false; - } - -} diff --git a/src/org/traccar/model/CellTower.java b/src/org/traccar/model/CellTower.java deleted file mode 100644 index 6d1dfbd7f..000000000 --- a/src/org/traccar/model/CellTower.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.annotation.JsonInclude; -import org.traccar.Context; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class CellTower { - - public static CellTower from(int mcc, int mnc, int lac, long cid) { - CellTower cellTower = new CellTower(); - cellTower.setMobileCountryCode(mcc); - cellTower.setMobileNetworkCode(mnc); - cellTower.setLocationAreaCode(lac); - cellTower.setCellId(cid); - return cellTower; - } - - public static CellTower from(int mcc, int mnc, int lac, long cid, int rssi) { - CellTower cellTower = CellTower.from(mcc, mnc, lac, cid); - cellTower.setSignalStrength(rssi); - return cellTower; - } - - public static CellTower fromLacCid(int lac, long cid) { - return from( - Context.getConfig().getInteger("geolocation.mcc"), - Context.getConfig().getInteger("geolocation.mnc"), lac, cid); - } - - public static CellTower fromCidLac(long cid, int lac) { - return fromLacCid(lac, cid); - } - - private String radioType; - - public String getRadioType() { - return radioType; - } - - public void setRadioType(String radioType) { - this.radioType = radioType; - } - - private Long cellId; - - public Long getCellId() { - return cellId; - } - - public void setCellId(Long cellId) { - this.cellId = cellId; - } - - private Integer locationAreaCode; - - public Integer getLocationAreaCode() { - return locationAreaCode; - } - - public void setLocationAreaCode(Integer locationAreaCode) { - this.locationAreaCode = locationAreaCode; - } - - private Integer mobileCountryCode; - - public Integer getMobileCountryCode() { - return mobileCountryCode; - } - - public void setMobileCountryCode(Integer mobileCountryCode) { - this.mobileCountryCode = mobileCountryCode; - } - - private Integer mobileNetworkCode; - - public Integer getMobileNetworkCode() { - return mobileNetworkCode; - } - - public void setMobileNetworkCode(Integer mobileNetworkCode) { - this.mobileNetworkCode = mobileNetworkCode; - } - - private Integer signalStrength; - - public Integer getSignalStrength() { - return signalStrength; - } - - public void setSignalStrength(Integer signalStrength) { - this.signalStrength = signalStrength; - } - - public void setOperator(long operator) { - String operatorString = String.valueOf(operator); - mobileCountryCode = Integer.parseInt(operatorString.substring(0, 3)); - mobileNetworkCode = Integer.parseInt(operatorString.substring(3)); - } - -} diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java deleted file mode 100644 index 336fc61f4..000000000 --- a/src/org/traccar/model/Command.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import org.traccar.database.QueryIgnore; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class Command extends Message implements Cloneable { - - public static final String TYPE_CUSTOM = "custom"; - public static final String TYPE_IDENTIFICATION = "deviceIdentification"; - public static final String TYPE_POSITION_SINGLE = "positionSingle"; - public static final String TYPE_POSITION_PERIODIC = "positionPeriodic"; - public static final String TYPE_POSITION_STOP = "positionStop"; - public static final String TYPE_ENGINE_STOP = "engineStop"; - public static final String TYPE_ENGINE_RESUME = "engineResume"; - public static final String TYPE_ALARM_ARM = "alarmArm"; - public static final String TYPE_ALARM_DISARM = "alarmDisarm"; - public static final String TYPE_SET_TIMEZONE = "setTimezone"; - public static final String TYPE_REQUEST_PHOTO = "requestPhoto"; - public static final String TYPE_POWER_OFF = "powerOff"; - public static final String TYPE_REBOOT_DEVICE = "rebootDevice"; - public static final String TYPE_SEND_SMS = "sendSms"; - public static final String TYPE_SEND_USSD = "sendUssd"; - public static final String TYPE_SOS_NUMBER = "sosNumber"; - public static final String TYPE_SILENCE_TIME = "silenceTime"; - public static final String TYPE_SET_PHONEBOOK = "setPhonebook"; - public static final String TYPE_MESSAGE = "message"; - public static final String TYPE_VOICE_MESSAGE = "voiceMessage"; - public static final String TYPE_OUTPUT_CONTROL = "outputControl"; - public static final String TYPE_VOICE_MONITORING = "voiceMonitoring"; - public static final String TYPE_SET_AGPS = "setAgps"; - public static final String TYPE_SET_INDICATOR = "setIndicator"; - public static final String TYPE_CONFIGURATION = "configuration"; - public static final String TYPE_GET_VERSION = "getVersion"; - public static final String TYPE_FIRMWARE_UPDATE = "firmwareUpdate"; - public static final String TYPE_SET_CONNECTION = "setConnection"; - public static final String TYPE_SET_ODOMETER = "setOdometer"; - public static final String TYPE_GET_MODEM_STATUS = "getModemStatus"; - public static final String TYPE_GET_DEVICE_STATUS = "getDeviceStatus"; - - public static final String TYPE_MODE_POWER_SAVING = "modePowerSaving"; - public static final String TYPE_MODE_DEEP_SLEEP = "modeDeepSleep"; - - public static final String TYPE_ALARM_GEOFENCE = "movementAlarm"; - public static final String TYPE_ALARM_BATTERY = "alarmBattery"; - public static final String TYPE_ALARM_SOS = "alarmSos"; - public static final String TYPE_ALARM_REMOVE = "alarmRemove"; - public static final String TYPE_ALARM_CLOCK = "alarmClock"; - public static final String TYPE_ALARM_SPEED = "alarmSpeed"; - public static final String TYPE_ALARM_FALL = "alarmFall"; - public static final String TYPE_ALARM_VIBRATION = "alarmVibration"; - - public static final String KEY_UNIQUE_ID = "uniqueId"; - public static final String KEY_FREQUENCY = "frequency"; - public static final String KEY_TIMEZONE = "timezone"; - public static final String KEY_DEVICE_PASSWORD = "devicePassword"; - public static final String KEY_RADIUS = "radius"; - public static final String KEY_MESSAGE = "message"; - public static final String KEY_ENABLE = "enable"; - public static final String KEY_DATA = "data"; - public static final String KEY_INDEX = "index"; - public static final String KEY_PHONE = "phone"; - public static final String KEY_SERVER = "server"; - public static final String KEY_PORT = "port"; - - @Override - public Command clone() throws CloneNotSupportedException { - return (Command) super.clone(); - } - - private boolean textChannel; - - public boolean getTextChannel() { - return textChannel; - } - - public void setTextChannel(boolean textChannel) { - this.textChannel = textChannel; - } - - @QueryIgnore - @Override - public long getDeviceId() { - return super.getDeviceId(); - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - -} diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java deleted file mode 100644 index 0c9be932d..000000000 --- a/src/org/traccar/model/Device.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.model; - -import java.util.Date; -import java.util.List; - -import org.traccar.database.QueryExtended; -import org.traccar.database.QueryIgnore; - -public class Device extends GroupedModel { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String uniqueId; - - public String getUniqueId() { - return uniqueId; - } - - public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; - } - - public static final String STATUS_UNKNOWN = "unknown"; - public static final String STATUS_ONLINE = "online"; - public static final String STATUS_OFFLINE = "offline"; - - private String status; - - @QueryIgnore - public String getStatus() { - return status != null ? status : STATUS_OFFLINE; - } - - public void setStatus(String status) { - this.status = status; - } - - private Date lastUpdate; - - @QueryExtended - public Date getLastUpdate() { - if (lastUpdate != null) { - return new Date(lastUpdate.getTime()); - } else { - return null; - } - } - - public void setLastUpdate(Date lastUpdate) { - if (lastUpdate != null) { - this.lastUpdate = new Date(lastUpdate.getTime()); - } else { - this.lastUpdate = null; - } - } - - private long positionId; - - @QueryIgnore - public long getPositionId() { - return positionId; - } - - public void setPositionId(long positionId) { - this.positionId = positionId; - } - - private List<Long> geofenceIds; - - @QueryIgnore - public List<Long> getGeofenceIds() { - return geofenceIds; - } - - public void setGeofenceIds(List<Long> geofenceIds) { - this.geofenceIds = geofenceIds; - } - - private String phone; - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - private String model; - - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - private String contact; - - public String getContact() { - return contact; - } - - public void setContact(String contact) { - this.contact = contact; - } - - private String category; - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - private boolean disabled; - - public boolean getDisabled() { - return disabled; - } - - public void setDisabled(boolean disabled) { - this.disabled = disabled; - } - -} diff --git a/src/org/traccar/model/DeviceAccumulators.java b/src/org/traccar/model/DeviceAccumulators.java deleted file mode 100644 index 8a90826c4..000000000 --- a/src/org/traccar/model/DeviceAccumulators.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - * 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 DeviceAccumulators { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private Double totalDistance; - - public Double getTotalDistance() { - return totalDistance; - } - - public void setTotalDistance(Double totalDistance) { - this.totalDistance = totalDistance; - } - - private Long hours; - - public Long getHours() { - return hours; - } - - public void setHours(Long hours) { - this.hours = hours; - } - -} diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java deleted file mode 100644 index 75d6726ee..000000000 --- a/src/org/traccar/model/DeviceState.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 DeviceState { - - private Boolean motionState; - - public void setMotionState(boolean motionState) { - this.motionState = motionState; - } - - public Boolean getMotionState() { - return motionState; - } - - private Position motionPosition; - - public void setMotionPosition(Position motionPosition) { - this.motionPosition = motionPosition; - } - - public Position getMotionPosition() { - return motionPosition; - } - - private Boolean overspeedState; - - public void setOverspeedState(boolean overspeedState) { - this.overspeedState = overspeedState; - } - - public Boolean getOverspeedState() { - return overspeedState; - } - - private Position overspeedPosition; - - public void setOverspeedPosition(Position overspeedPosition) { - this.overspeedPosition = overspeedPosition; - } - - public Position getOverspeedPosition() { - 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/Driver.java b/src/org/traccar/model/Driver.java deleted file mode 100644 index 05f52fd4d..000000000 --- a/src/org/traccar/model/Driver.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 Driver extends ExtendedModel { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String uniqueId; - - public String getUniqueId() { - return uniqueId; - } - - public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; - } -} diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java deleted file mode 100644 index ee7fcc679..000000000 --- a/src/org/traccar/model/Event.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import java.util.Date; - -public class Event extends Message { - - public Event(String type, long deviceId, long positionId) { - this(type, deviceId); - setPositionId(positionId); - } - - public Event(String type, long deviceId) { - setType(type); - setDeviceId(deviceId); - this.serverTime = new Date(); - } - - public Event() { - } - - public static final String ALL_EVENTS = "allEvents"; - - public static final String TYPE_COMMAND_RESULT = "commandResult"; - - public static final String TYPE_DEVICE_ONLINE = "deviceOnline"; - public static final String TYPE_DEVICE_UNKNOWN = "deviceUnknown"; - public static final String TYPE_DEVICE_OFFLINE = "deviceOffline"; - - public static final String TYPE_DEVICE_MOVING = "deviceMoving"; - public static final String TYPE_DEVICE_STOPPED = "deviceStopped"; - - public static final String TYPE_DEVICE_OVERSPEED = "deviceOverspeed"; - public static final String TYPE_DEVICE_FUEL_DROP = "deviceFuelDrop"; - - public static final String TYPE_GEOFENCE_ENTER = "geofenceEnter"; - public static final String TYPE_GEOFENCE_EXIT = "geofenceExit"; - - public static final String TYPE_ALARM = "alarm"; - - public static final String TYPE_IGNITION_ON = "ignitionOn"; - public static final String TYPE_IGNITION_OFF = "ignitionOff"; - - public static final String TYPE_MAINTENANCE = "maintenance"; - - public static final String TYPE_TEXT_MESSAGE = "textMessage"; - - public static final String TYPE_DRIVER_CHANGED = "driverChanged"; - - private Date serverTime; - - public Date getServerTime() { - return serverTime; - } - - public void setServerTime(Date serverTime) { - this.serverTime = serverTime; - } - - private long positionId; - - public long getPositionId() { - return positionId; - } - - public void setPositionId(long positionId) { - this.positionId = positionId; - } - - private long geofenceId = 0; - - public long getGeofenceId() { - return geofenceId; - } - - public void setGeofenceId(long geofenceId) { - 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/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java deleted file mode 100644 index 8353d0e66..000000000 --- a/src/org/traccar/model/ExtendedModel.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class ExtendedModel extends BaseModel { - - private Map<String, Object> attributes = new LinkedHashMap<>(); - - public Map<String, Object> getAttributes() { - return attributes; - } - - public void setAttributes(Map<String, Object> attributes) { - this.attributes = attributes; - } - - public void set(String key, Boolean value) { - if (value != null) { - attributes.put(key, value); - } - } - - public void set(String key, Byte value) { - if (value != null) { - attributes.put(key, value.intValue()); - } - } - - public void set(String key, Short value) { - if (value != null) { - attributes.put(key, value.intValue()); - } - } - - public void set(String key, Integer value) { - if (value != null) { - attributes.put(key, value); - } - } - - public void set(String key, Long value) { - if (value != null) { - attributes.put(key, value); - } - } - - public void set(String key, Float value) { - if (value != null) { - attributes.put(key, value.doubleValue()); - } - } - - public void set(String key, Double value) { - if (value != null) { - attributes.put(key, value); - } - } - - public void set(String key, String value) { - if (value != null && !value.isEmpty()) { - attributes.put(key, value); - } - } - - public void add(Map.Entry<String, Object> entry) { - if (entry != null && entry.getValue() != null) { - attributes.put(entry.getKey(), entry.getValue()); - } - } - - public String getString(String key) { - if (attributes.containsKey(key)) { - return (String) attributes.get(key); - } else { - return null; - } - } - - public double getDouble(String key) { - if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).doubleValue(); - } else { - return 0.0; - } - } - - public boolean getBoolean(String key) { - if (attributes.containsKey(key)) { - return (Boolean) attributes.get(key); - } else { - return false; - } - } - - public int getInteger(String key) { - if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).intValue(); - } else { - return 0; - } - } - - public long getLong(String key) { - if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).longValue(); - } else { - return 0; - } - } - -} diff --git a/src/org/traccar/model/Geofence.java b/src/org/traccar/model/Geofence.java deleted file mode 100644 index 8560d22e9..000000000 --- a/src/org/traccar/model/Geofence.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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; - -import java.text.ParseException; - -import org.traccar.Context; -import org.traccar.database.QueryIgnore; -import org.traccar.geofence.GeofenceCircle; -import org.traccar.geofence.GeofenceGeometry; -import org.traccar.geofence.GeofencePolygon; -import org.traccar.geofence.GeofencePolyline; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -public class Geofence extends ScheduledModel { - - public static final String TYPE_GEOFENCE_CILCLE = "geofenceCircle"; - public static final String TYPE_GEOFENCE_POLYGON = "geofencePolygon"; - public static final String TYPE_GEOFENCE_POLYLINE = "geofencePolyline"; - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - private String area; - - public String getArea() { - return area; - } - - public void setArea(String area) throws ParseException { - - if (area.startsWith("CIRCLE")) { - geometry = new GeofenceCircle(area); - } else if (area.startsWith("POLYGON")) { - geometry = new GeofencePolygon(area); - } else if (area.startsWith("LINESTRING")) { - 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); - } - - this.area = area; - } - - private GeofenceGeometry geometry; - - @QueryIgnore - @JsonIgnore - public GeofenceGeometry getGeometry() { - return geometry; - } - - @QueryIgnore - @JsonIgnore - public void setGeometry(GeofenceGeometry geometry) { - area = geometry.toWkt(); - this.geometry = geometry; - } -} diff --git a/src/org/traccar/model/Group.java b/src/org/traccar/model/Group.java deleted file mode 100644 index 91ea2319d..000000000 --- a/src/org/traccar/model/Group.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - * 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 Group extends GroupedModel { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/src/org/traccar/model/GroupedModel.java b/src/org/traccar/model/GroupedModel.java deleted file mode 100644 index 6b1aa75b1..000000000 --- a/src/org/traccar/model/GroupedModel.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 GroupedModel extends ExtendedModel { - - private long groupId; - - public long getGroupId() { - return groupId; - } - - public void setGroupId(long groupId) { - this.groupId = groupId; - } - -} diff --git a/src/org/traccar/model/Maintenance.java b/src/org/traccar/model/Maintenance.java deleted file mode 100644 index 73f67ea96..000000000 --- a/src/org/traccar/model/Maintenance.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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/ManagedUser.java b/src/org/traccar/model/ManagedUser.java deleted file mode 100644 index 03c5ef48d..000000000 --- a/src/org/traccar/model/ManagedUser.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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 ManagedUser extends User { - -} diff --git a/src/org/traccar/model/Message.java b/src/org/traccar/model/Message.java deleted file mode 100644 index dad9c20f0..000000000 --- a/src/org/traccar/model/Message.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013 - 2016 Anton Tananaev (anton@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 Message extends ExtendedModel { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String type; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - -} diff --git a/src/org/traccar/model/MiscFormatter.java b/src/org/traccar/model/MiscFormatter.java deleted file mode 100644 index c6511f063..000000000 --- a/src/org/traccar/model/MiscFormatter.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013 - 2016 Anton Tananaev (anton@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; - - -import java.text.DecimalFormat; -import java.util.Map; - -public final class MiscFormatter { - - private MiscFormatter() { - } - - private static final String XML_ROOT_NODE = "info"; - - private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##"); - - private static String format(Object value) { - if (value instanceof Double || value instanceof Float) { - return DECIMAL_FORMAT.format(value); - } else { - return value.toString(); - } - } - - public static String toXmlString(Map<String, Object> attributes) { - StringBuilder result = new StringBuilder(); - - result.append("<").append(XML_ROOT_NODE).append(">"); - - for (Map.Entry<String, Object> entry : attributes.entrySet()) { - - result.append("<").append(entry.getKey()).append(">"); - result.append(format(entry.getValue())); - result.append("</").append(entry.getKey()).append(">"); - } - - result.append("</").append(XML_ROOT_NODE).append(">"); - - return result.toString(); - } - -} diff --git a/src/org/traccar/model/Network.java b/src/org/traccar/model/Network.java deleted file mode 100644 index 2d56950f1..000000000 --- a/src/org/traccar/model/Network.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.annotation.JsonInclude; - -import java.util.ArrayList; -import java.util.Collection; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class Network { - - public Network() { - } - - public Network(CellTower cellTower) { - addCellTower(cellTower); - } - - private Integer homeMobileCountryCode; - - public Integer getHomeMobileCountryCode() { - return homeMobileCountryCode; - } - - public void setHomeMobileCountryCode(Integer homeMobileCountryCode) { - this.homeMobileCountryCode = homeMobileCountryCode; - } - - private Integer homeMobileNetworkCode; - - public Integer getHomeMobileNetworkCode() { - return homeMobileNetworkCode; - } - - public void setHomeMobileNetworkCode(Integer homeMobileNetworkCode) { - this.homeMobileNetworkCode = homeMobileNetworkCode; - } - - private String radioType = "gsm"; - - public String getRadioType() { - return radioType; - } - - public void setRadioType(String radioType) { - this.radioType = radioType; - } - - private String carrier; - - public String getCarrier() { - return carrier; - } - - public void setCarrier(String carrier) { - this.carrier = carrier; - } - - private Boolean considerIp = false; - - public Boolean getConsiderIp() { - return considerIp; - } - - public void setConsiderIp(Boolean considerIp) { - this.considerIp = considerIp; - } - - private Collection<CellTower> cellTowers; - - public Collection<CellTower> getCellTowers() { - return cellTowers; - } - - public void setCellTowers(Collection<CellTower> cellTowers) { - this.cellTowers = cellTowers; - } - - public void addCellTower(CellTower cellTower) { - if (cellTowers == null) { - cellTowers = new ArrayList<>(); - } - cellTowers.add(cellTower); - } - - private Collection<WifiAccessPoint> wifiAccessPoints; - - public Collection<WifiAccessPoint> getWifiAccessPoints() { - return wifiAccessPoints; - } - - public void setWifiAccessPoints(Collection<WifiAccessPoint> wifiAccessPoints) { - this.wifiAccessPoints = wifiAccessPoints; - } - - public void addWifiAccessPoint(WifiAccessPoint wifiAccessPoint) { - if (wifiAccessPoints == null) { - wifiAccessPoints = new ArrayList<>(); - } - wifiAccessPoints.add(wifiAccessPoint); - } - -} diff --git a/src/org/traccar/model/Notification.java b/src/org/traccar/model/Notification.java deleted file mode 100644 index f1983a03a..000000000 --- a/src/org/traccar/model/Notification.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * 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; - -import java.util.HashSet; -import java.util.Set; - -import org.traccar.database.QueryIgnore; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -public class Notification extends ScheduledModel { - - private boolean always; - - public boolean getAlways() { - return always; - } - - public void setAlways(boolean always) { - this.always = always; - } - - private String type; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - - private String notificators; - - public String getNotificators() { - return notificators; - } - - public void setNotificators(String transports) { - this.notificators = transports; - } - - - @JsonIgnore - @QueryIgnore - public Set<String> getNotificatorsTypes() { - final Set<String> result = new HashSet<>(); - if (notificators != null) { - final String[] transportsList = notificators.split(","); - for (String transport : transportsList) { - result.add(transport.trim()); - } - } - return result; - } - -} diff --git a/src/org/traccar/model/Permission.java b/src/org/traccar/model/Permission.java deleted file mode 100644 index 1006b1c47..000000000 --- a/src/org/traccar/model/Permission.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.traccar.database.DataManager; - -public class Permission { - - private Class<?> ownerClass; - private long ownerId; - private Class<?> propertyClass; - private long propertyId; - - public Permission(LinkedHashMap<String, Long> permissionMap) throws ClassNotFoundException { - Iterator<Map.Entry<String, Long>> iterator = permissionMap.entrySet().iterator(); - String owner = iterator.next().getKey(); - ownerClass = DataManager.getClassByName(owner); - String property = iterator.next().getKey(); - propertyClass = DataManager.getClassByName(property); - ownerId = permissionMap.get(owner); - propertyId = permissionMap.get(property); - } - - public Class<?> getOwnerClass() { - return ownerClass; - } - - public long getOwnerId() { - return ownerId; - } - - public Class<?> getPropertyClass() { - return propertyClass; - } - - public long getPropertyId() { - return propertyId; - } -} diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java deleted file mode 100644 index 4b327cbd2..000000000 --- a/src/org/traccar/model/Position.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2012 - 2016 Anton Tananaev (anton@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; - -import java.util.Date; - -import org.traccar.database.QueryIgnore; - -public class Position extends Message { - - public static final String KEY_ORIGINAL = "raw"; - public static final String KEY_INDEX = "index"; - public static final String KEY_HDOP = "hdop"; - public static final String KEY_VDOP = "vdop"; - public static final String KEY_PDOP = "pdop"; - public static final String KEY_SATELLITES = "sat"; // in use - public static final String KEY_SATELLITES_VISIBLE = "satVisible"; - public static final String KEY_RSSI = "rssi"; - public static final String KEY_GPS = "gps"; - public static final String KEY_ROAMING = "roaming"; - public static final String KEY_EVENT = "event"; - public static final String KEY_ALARM = "alarm"; - public static final String KEY_STATUS = "status"; - public static final String KEY_ODOMETER = "odometer"; // meters - public static final String KEY_ODOMETER_SERVICE = "serviceOdometer"; // meters - 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"; - public static final String KEY_VIDEO = "video"; - public static final String KEY_AUDIO = "audio"; - - // The units for the below four KEYs currently vary. - // The preferred units of measure are specified in the comment for each. - public static final String KEY_POWER = "power"; // volts - 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"; - public static final String KEY_VERSION_HW = "versionHw"; - public static final String KEY_TYPE = "type"; - public static final String KEY_IGNITION = "ignition"; - public static final String KEY_FLAGS = "flags"; - 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"; - public static final String KEY_DISTANCE = "distance"; // meters - public static final String KEY_TOTAL_DISTANCE = "totalDistance"; // meters - public static final String KEY_RPM = "rpm"; - public static final String KEY_VIN = "vin"; - public static final String KEY_APPROXIMATE = "approximate"; - public static final String KEY_THROTTLE = "throttle"; - public static final String KEY_MOTION = "motion"; - public static final String KEY_ARMED = "armed"; - public static final String KEY_GEOFENCE = "geofence"; - public static final String KEY_ACCELERATION = "acceleration"; - public static final String KEY_DEVICE_TEMP = "deviceTemp"; // celsius - public static final String KEY_COOLANT_TEMP = "coolantTemp"; // celsius - public static final String KEY_ENGINE_LOAD = "engineLoad"; - public static final String KEY_OPERATOR = "operator"; - public static final String KEY_COMMAND = "command"; - public static final String KEY_BLOCKED = "blocked"; - public static final String KEY_DOOR = "door"; - public static final String KEY_AXLE_WEIGHT = "axleWeight"; - - public static final String KEY_DTCS = "dtcs"; - public static final String KEY_OBD_SPEED = "obdSpeed"; // knots - public static final String KEY_OBD_ODOMETER = "obdOdometer"; // meters - - public static final String KEY_RESULT = "result"; - - public static final String KEY_DRIVER_UNIQUE_ID = "driverUniqueId"; - - // Start with 1 not 0 - public static final String PREFIX_TEMP = "temp"; - public static final String PREFIX_ADC = "adc"; - public static final String PREFIX_IO = "io"; - public static final String PREFIX_COUNT = "count"; - public static final String PREFIX_IN = "in"; - public static final String PREFIX_OUT = "out"; - - public static final String ALARM_GENERAL = "general"; - public static final String ALARM_SOS = "sos"; - public static final String ALARM_VIBRATION = "vibration"; - public static final String ALARM_MOVEMENT = "movement"; - public static final String ALARM_LOW_SPEED = "lowspeed"; - public static final String ALARM_OVERSPEED = "overspeed"; - public static final String ALARM_FALL_DOWN = "fallDown"; - public static final String ALARM_LOW_POWER = "lowPower"; - public static final String ALARM_LOW_BATTERY = "lowBattery"; - public static final String ALARM_FAULT = "fault"; - 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"; - public static final String ALARM_GPS_ANTENNA_CUT = "gpsAntennaCut"; - public static final String ALARM_ACCIDENT = "accident"; - public static final String ALARM_TOW = "tow"; - public static final String ALARM_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"; - public static final String ALARM_JAMMING = "jamming"; - public static final String ALARM_TEMPERATURE = "temperature"; - public static final String ALARM_PARKING = "parking"; - 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_FUEL_LEAK = "fuelLeak"; - public static final String ALARM_TAMPERING = "tampering"; - public static final String ALARM_REMOVING = "removing"; - - public Position() { - } - - public Position(String protocol) { - this.protocol = protocol; - this.serverTime = new Date(); - } - - private String protocol; - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - private Date serverTime; - - public Date getServerTime() { - return serverTime; - } - - public void setServerTime(Date serverTime) { - this.serverTime = serverTime; - } - - private Date deviceTime; - - public Date getDeviceTime() { - return deviceTime; - } - - public void setDeviceTime(Date deviceTime) { - this.deviceTime = deviceTime; - } - - private Date fixTime; - - public Date getFixTime() { - return fixTime; - } - - public void setFixTime(Date fixTime) { - this.fixTime = fixTime; - } - - public void setTime(Date time) { - setDeviceTime(time); - setFixTime(time); - } - - private boolean outdated; - - @QueryIgnore - public boolean getOutdated() { - return outdated; - } - - public void setOutdated(boolean outdated) { - this.outdated = outdated; - } - - private boolean valid; - - public boolean getValid() { - return valid; - } - - public void setValid(boolean valid) { - this.valid = valid; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private double altitude; // value in meters - - public double getAltitude() { - return altitude; - } - - public void setAltitude(double altitude) { - this.altitude = altitude; - } - - private double speed; // value in knots - - public double getSpeed() { - return speed; - } - - public void setSpeed(double speed) { - this.speed = speed; - } - - private double course; - - public double getCourse() { - return course; - } - - public void setCourse(double course) { - this.course = course; - } - - private String address; - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - private double accuracy; - - public double getAccuracy() { - return accuracy; - } - - public void setAccuracy(double accuracy) { - this.accuracy = accuracy; - } - - private Network network; - - public Network getNetwork() { - return network; - } - - public void setNetwork(Network network) { - this.network = network; - } - - @Override - @QueryIgnore - public String getType() { - return super.getType(); - } - -} diff --git a/src/org/traccar/model/ScheduledModel.java b/src/org/traccar/model/ScheduledModel.java deleted file mode 100644 index 9e6a4b9a6..000000000 --- a/src/org/traccar/model/ScheduledModel.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 ScheduledModel extends ExtendedModel { - - private long calendarId; - - public long getCalendarId() { - return calendarId; - } - - public void setCalendarId(long calendarId) { - this.calendarId = calendarId; - } -} diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java deleted file mode 100644 index ad37e7078..000000000 --- a/src/org/traccar/model/Server.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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; - -import org.traccar.database.QueryIgnore; - -public class Server extends ExtendedModel { - - @QueryIgnore - public String getVersion() { - return getClass().getPackage().getImplementationVersion(); - } - - public void setVersion(String version) { - } - - private boolean registration; - - public boolean getRegistration() { - return registration; - } - - public void setRegistration(boolean registration) { - this.registration = registration; - } - - private boolean readonly; - - public boolean getReadonly() { - return readonly; - } - - public void setReadonly(boolean readonly) { - this.readonly = readonly; - } - - private boolean deviceReadonly; - - public boolean getDeviceReadonly() { - return deviceReadonly; - } - - public void setDeviceReadonly(boolean deviceReadonly) { - this.deviceReadonly = deviceReadonly; - } - - private String map; - - public String getMap() { - return map; - } - - public void setMap(String map) { - this.map = map; - } - - private String bingKey; - - public String getBingKey() { - return bingKey; - } - - public void setBingKey(String bingKey) { - this.bingKey = bingKey; - } - - private String mapUrl; - - public String getMapUrl() { - return mapUrl; - } - - public void setMapUrl(String mapUrl) { - this.mapUrl = mapUrl; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private int zoom; - - public int getZoom() { - return zoom; - } - - public void setZoom(int zoom) { - this.zoom = zoom; - } - - private boolean twelveHourFormat; - - public boolean getTwelveHourFormat() { - return twelveHourFormat; - } - - public void setTwelveHourFormat(boolean twelveHourFormat) { - this.twelveHourFormat = twelveHourFormat; - } - - private boolean forceSettings; - - public boolean getForceSettings() { - return forceSettings; - } - - public void setForceSettings(boolean forceSettings) { - this.forceSettings = forceSettings; - } - - private String coordinateFormat; - - public String getCoordinateFormat() { - return coordinateFormat; - } - - public void setCoordinateFormat(String coordinateFormat) { - this.coordinateFormat = coordinateFormat; - } - - private boolean limitCommands; - - public boolean getLimitCommands() { - return limitCommands; - } - - public void setLimitCommands(boolean limitCommands) { - this.limitCommands = limitCommands; - } - - private String poiLayer; - - public String getPoiLayer() { - return poiLayer; - } - - public void setPoiLayer(String poiLayer) { - this.poiLayer = poiLayer; - } -} diff --git a/src/org/traccar/model/Statistics.java b/src/org/traccar/model/Statistics.java deleted file mode 100644 index cb72c91dd..000000000 --- a/src/org/traccar/model/Statistics.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import java.util.Date; - -public class Statistics extends ExtendedModel { - - private Date captureTime; - - public Date getCaptureTime() { - return captureTime; - } - - public void setCaptureTime(Date captureTime) { - this.captureTime = captureTime; - } - - private int activeUsers; - - public int getActiveUsers() { - return activeUsers; - } - - public void setActiveUsers(int activeUsers) { - this.activeUsers = activeUsers; - } - - private int activeDevices; - - public int getActiveDevices() { - return activeDevices; - } - - public void setActiveDevices(int activeDevices) { - this.activeDevices = activeDevices; - } - - private int requests; - - public int getRequests() { - return requests; - } - - public void setRequests(int requests) { - this.requests = requests; - } - - private int messagesReceived; - - public int getMessagesReceived() { - return messagesReceived; - } - - public void setMessagesReceived(int messagesReceived) { - this.messagesReceived = messagesReceived; - } - - private int messagesStored; - - public int getMessagesStored() { - return messagesStored; - } - - public void setMessagesStored(int messagesStored) { - this.messagesStored = messagesStored; - } - - private int mailSent; - - public int getMailSent() { - return mailSent; - } - - public void setMailSent(int mailSent) { - this.mailSent = mailSent; - } - - private int smsSent; - - public int getSmsSent() { - return smsSent; - } - - public void setSmsSent(int smsSent) { - this.smsSent = smsSent; - } - - private int geocoderRequests; - - public int getGeocoderRequests() { - return geocoderRequests; - } - - public void setGeocoderRequests(int geocoderRequests) { - this.geocoderRequests = geocoderRequests; - } - - private int geolocationRequests; - - public int getGeolocationRequests() { - return geolocationRequests; - } - - public void setGeolocationRequests(int geolocationRequests) { - this.geolocationRequests = geolocationRequests; - } - -} diff --git a/src/org/traccar/model/Typed.java b/src/org/traccar/model/Typed.java deleted file mode 100644 index 313ec7bcd..000000000 --- a/src/org/traccar/model/Typed.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) - * - * 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 Typed { - - private String type; - - public Typed(String type) { - this.type = type; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } -} diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java deleted file mode 100644 index 976b6aac0..000000000 --- a/src/org/traccar/model/User.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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. - * 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; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -import org.traccar.database.QueryExtended; -import org.traccar.database.QueryIgnore; -import org.traccar.helper.Hashing; - -import java.util.Date; - -public class User extends ExtendedModel { - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - private String login; - - public String getLogin() { - return login; - } - - public void setLogin(String login) { - this.login = login; - } - - private String email; - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email.trim(); - } - - private String phone; - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - private boolean readonly; - - public boolean getReadonly() { - return readonly; - } - - public void setReadonly(boolean readonly) { - this.readonly = readonly; - } - - private boolean administrator; - - public boolean getAdministrator() { - return administrator; - } - - public void setAdministrator(boolean administrator) { - this.administrator = administrator; - } - - private String map; - - public String getMap() { - return map; - } - - public void setMap(String map) { - this.map = map; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private int zoom; - - public int getZoom() { - return zoom; - } - - public void setZoom(int zoom) { - this.zoom = zoom; - } - - private boolean twelveHourFormat; - - public boolean getTwelveHourFormat() { - return twelveHourFormat; - } - - public void setTwelveHourFormat(boolean twelveHourFormat) { - this.twelveHourFormat = twelveHourFormat; - } - - private String coordinateFormat; - - public String getCoordinateFormat() { - return coordinateFormat; - } - - public void setCoordinateFormat(String coordinateFormat) { - this.coordinateFormat = coordinateFormat; - } - - private boolean disabled; - - public boolean getDisabled() { - return disabled; - } - - public void setDisabled(boolean disabled) { - this.disabled = disabled; - } - - private Date expirationTime; - - public Date getExpirationTime() { - return expirationTime; - } - - public void setExpirationTime(Date expirationTime) { - this.expirationTime = expirationTime; - } - - private int deviceLimit; - - public int getDeviceLimit() { - return deviceLimit; - } - - public void setDeviceLimit(int deviceLimit) { - this.deviceLimit = deviceLimit; - } - - private int userLimit; - - public int getUserLimit() { - return userLimit; - } - - public void setUserLimit(int userLimit) { - this.userLimit = userLimit; - } - - private boolean deviceReadonly; - - public boolean getDeviceReadonly() { - return deviceReadonly; - } - - public void setDeviceReadonly(boolean deviceReadonly) { - this.deviceReadonly = deviceReadonly; - } - - private String token; - - public String getToken() { - return token; - } - - public void setToken(String token) { - if (token != null && !token.isEmpty()) { - if (!token.matches("^[a-zA-Z0-9-]{16,}$")) { - throw new IllegalArgumentException("Illegal token"); - } - this.token = token; - } else { - this.token = null; - } - } - - private boolean limitCommands; - - public boolean getLimitCommands() { - return limitCommands; - } - - public void setLimitCommands(boolean limitCommands) { - this.limitCommands = limitCommands; - } - - private String poiLayer; - - public String getPoiLayer() { - return poiLayer; - } - - public void setPoiLayer(String poiLayer) { - this.poiLayer = poiLayer; - } - - @QueryIgnore - public String getPassword() { - return null; - } - - public void setPassword(String password) { - if (password != null && !password.isEmpty()) { - Hashing.HashingResult hashingResult = Hashing.createHash(password); - hashedPassword = hashingResult.getHash(); - salt = hashingResult.getSalt(); - } - } - - private String hashedPassword; - - @JsonIgnore - @QueryExtended - public String getHashedPassword() { - return hashedPassword; - } - - public void setHashedPassword(String hashedPassword) { - this.hashedPassword = hashedPassword; - } - - private String salt; - - @JsonIgnore - @QueryExtended - public String getSalt() { - return salt; - } - - public void setSalt(String salt) { - this.salt = salt; - } - - public boolean isPasswordValid(String password) { - return Hashing.validatePassword(password, hashedPassword, salt); - } - -} diff --git a/src/org/traccar/model/WifiAccessPoint.java b/src/org/traccar/model/WifiAccessPoint.java deleted file mode 100644 index 87a77f3c0..000000000 --- a/src/org/traccar/model/WifiAccessPoint.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class WifiAccessPoint { - - public static WifiAccessPoint from(String macAddress, int signalStrength) { - WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); - wifiAccessPoint.setMacAddress(macAddress); - wifiAccessPoint.setSignalStrength(signalStrength); - return wifiAccessPoint; - } - - public static WifiAccessPoint from(String macAddress, int signalStrength, int channel) { - WifiAccessPoint wifiAccessPoint = from(macAddress, signalStrength); - wifiAccessPoint.setChannel(channel); - return wifiAccessPoint; - } - - private String macAddress; - - public String getMacAddress() { - return macAddress; - } - - public void setMacAddress(String macAddress) { - this.macAddress = macAddress; - } - - private Integer signalStrength; - - public Integer getSignalStrength() { - return signalStrength; - } - - public void setSignalStrength(Integer signalStrength) { - this.signalStrength = signalStrength; - } - - private Integer channel; - - public Integer getChannel() { - return channel; - } - - public void setChannel(Integer channel) { - this.channel = channel; - } - -} diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java deleted file mode 100644 index c0010ebbd..000000000 --- a/src/org/traccar/notification/EventForwarder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.notification; - -import org.traccar.Context; -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 javax.ws.rs.client.AsyncInvoker; -import javax.ws.rs.client.Invocation; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public abstract class EventForwarder { - - private final String url; - private final String header; - - public EventForwarder() { - url = Context.getConfig().getString("event.forward.url", "http://localhost/"); - header = Context.getConfig().getString("event.forward.header"); - } - - private static final String KEY_POSITION = "position"; - private static final String KEY_EVENT = "event"; - private static final String KEY_GEOFENCE = "geofence"; - private static final String KEY_DEVICE = "device"; - 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) { - - Invocation.Builder requestBuilder = Context.getClient().target(url).request(); - - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - requestBuilder.header(values[0].trim(), values[1].trim()); - } - } - - executeRequest(event, position, users, requestBuilder.async()); - } - - 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) { - data.put(KEY_POSITION, position); - } - Device device = Context.getIdentityManager().getById(event.getDeviceId()); - if (device != null) { - data.put(KEY_DEVICE, device); - } - if (event.getGeofenceId() != 0) { - Geofence geofence = Context.getGeofenceManager().getById(event.getGeofenceId()); - if (geofence != null) { - data.put(KEY_GEOFENCE, geofence); - } - } - 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 void executeRequest( - Event event, Position position, Set<Long> users, AsyncInvoker invoker); - -} diff --git a/src/org/traccar/notification/FullMessage.java b/src/org/traccar/notification/FullMessage.java deleted file mode 100644 index f66537c6e..000000000 --- a/src/org/traccar/notification/FullMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.notification; - -public class FullMessage { - - private String subject; - private String body; - - public FullMessage(String subject, String body) { - this.subject = subject; - this.body = body; - } - - public String getSubject() { - return subject; - } - - public String getBody() { - return body; - } -} diff --git a/src/org/traccar/notification/JsonTypeEventForwarder.java b/src/org/traccar/notification/JsonTypeEventForwarder.java deleted file mode 100644 index fcafb964a..000000000 --- a/src/org/traccar/notification/JsonTypeEventForwarder.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.traccar.notification;
-
-import java.util.Set;
-
-import org.traccar.model.Event;
-import org.traccar.model.Position;
-
-import javax.ws.rs.client.AsyncInvoker;
-import javax.ws.rs.client.Entity;
-
-public class JsonTypeEventForwarder extends EventForwarder {
-
- @Override
- 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/MessageException.java b/src/org/traccar/notification/MessageException.java deleted file mode 100644 index 710b927b0..000000000 --- a/src/org/traccar/notification/MessageException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.notification; - -public class MessageException extends Exception { - - public MessageException(Throwable cause) { - super(cause); - } - - public MessageException(String message) { - super(message); - } - -} diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java deleted file mode 100644 index 2f8100226..000000000 --- a/src/org/traccar/notification/NotificationFormatter.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - * 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.notification; - -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; -import java.util.Locale; - -import org.apache.velocity.Template; -import org.apache.velocity.VelocityContext; -import org.apache.velocity.exception.ResourceNotFoundException; -import org.apache.velocity.tools.generic.DateTool; -import org.apache.velocity.tools.generic.NumberTool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.model.User; -import org.traccar.reports.ReportUtils; - -public final class NotificationFormatter { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificationFormatter.class); - - private NotificationFormatter() { - } - - public static VelocityContext prepareContext(long userId, Event event, Position position) { - - User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getById(event.getDeviceId()); - - VelocityContext velocityContext = new VelocityContext(); - velocityContext.put("user", user); - velocityContext.put("device", device); - velocityContext.put("event", event); - if (position != null) { - velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(userId)); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(userId)); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(userId)); - } - 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)); - } - velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); - velocityContext.put("dateTool", new DateTool()); - velocityContext.put("numberTool", new NumberTool()); - velocityContext.put("timezone", ReportUtils.getTimezone(userId)); - velocityContext.put("locale", Locale.getDefault()); - return velocityContext; - } - - public static Template getTemplate(Event event, String path) { - - String templateFilePath; - Template template; - - try { - templateFilePath = Paths.get(path, event.getType() + ".vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); - } catch (ResourceNotFoundException error) { - LOGGER.warn("Notification template error", error); - templateFilePath = Paths.get(path, "unknown.vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); - } - return template; - } - - public static FullMessage formatFullMessage(long userId, Event event, Position position) { - VelocityContext velocityContext = prepareContext(userId, event, position); - String formattedMessage = formatMessage(velocityContext, userId, event, position, "full"); - - return new FullMessage((String) velocityContext.get("subject"), formattedMessage); - } - - public static String formatShortMessage(long userId, Event event, Position position) { - return formatMessage(null, userId, event, position, "short"); - } - - private static String formatMessage(VelocityContext vc, Long userId, Event event, Position position, - String templatePath) { - - VelocityContext velocityContext = vc; - if (velocityContext == null) { - velocityContext = prepareContext(userId, event, position); - } - StringWriter writer = new StringWriter(); - getTemplate(event, templatePath).merge(velocityContext, writer); - - return writer.toString(); - } - -} diff --git a/src/org/traccar/notification/NotificatorManager.java b/src/org/traccar/notification/NotificatorManager.java deleted file mode 100644 index a4080a38d..000000000 --- a/src/org/traccar/notification/NotificatorManager.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.notification; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Typed; -import org.traccar.notificators.NotificatorFirebase; -import org.traccar.notificators.NotificatorMail; -import org.traccar.notificators.NotificatorNull; -import org.traccar.notificators.Notificator; -import org.traccar.notificators.NotificatorSms; -import org.traccar.notificators.NotificatorWeb; - -public final class NotificatorManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); - - private static final Notificator NULL_NOTIFICATOR = new NotificatorNull(); - - private final Map<String, Notificator> notificators = new HashMap<>(); - - public NotificatorManager() { - final String[] types = Context.getConfig().getString("notificator.types", "").split(","); - for (String type : types) { - String defaultNotificator = ""; - switch (type) { - case "web": - defaultNotificator = NotificatorWeb.class.getCanonicalName(); - break; - case "mail": - defaultNotificator = NotificatorMail.class.getCanonicalName(); - break; - case "sms": - defaultNotificator = NotificatorSms.class.getCanonicalName(); - break; - case "firebase": - defaultNotificator = NotificatorFirebase.class.getCanonicalName(); - break; - default: - break; - } - final String className = Context.getConfig() - .getString("notificator." + type + ".class", defaultNotificator); - try { - notificators.put(type, (Notificator) Class.forName(className).newInstance()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - LOGGER.warn("Unable to load notificator class for " + type + " " + className + " " + e.getMessage()); - } - } - } - - public Notificator getNotificator(String type) { - final Notificator notificator = notificators.get(type); - if (notificator == null) { - LOGGER.warn("No notificator configured for type : " + type); - return NULL_NOTIFICATOR; - } - return notificator; - } - - public Set<Typed> getAllNotificatorTypes() { - Set<Typed> result = new HashSet<>(); - for (String notificator : notificators.keySet()) { - result.add(new Typed(notificator)); - } - return result; - } - -} diff --git a/src/org/traccar/notification/PropertiesProvider.java b/src/org/traccar/notification/PropertiesProvider.java deleted file mode 100644 index f0078feef..000000000 --- a/src/org/traccar/notification/PropertiesProvider.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.notification; - -import org.traccar.config.Config; -import org.traccar.model.ExtendedModel; - -public class PropertiesProvider { - - private Config config; - - private ExtendedModel extendedModel; - - public PropertiesProvider(Config config) { - this.config = config; - } - - public PropertiesProvider(ExtendedModel extendedModel) { - this.extendedModel = extendedModel; - } - - public String getString(String key) { - if (config != null) { - return config.getString(key); - } else { - return extendedModel.getString(key); - } - } - - public String getString(String key, String defaultValue) { - String value = getString(key); - if (value == null) { - value = defaultValue; - } - return value; - } - - public int getInteger(String key, int defaultValue) { - if (config != null) { - return config.getInteger(key, defaultValue); - } else { - Object result = extendedModel.getAttributes().get(key); - if (result != null) { - return result instanceof String ? Integer.parseInt((String) result) : (Integer) result; - } else { - return defaultValue; - } - } - } - - public Boolean getBoolean(String key) { - if (config != null) { - if (config.hasKey(key)) { - return config.getBoolean(key); - } else { - return null; - } - } else { - Object result = extendedModel.getAttributes().get(key); - if (result != null) { - return result instanceof String ? Boolean.valueOf((String) result) : (Boolean) result; - } else { - return null; - } - } - } - -} diff --git a/src/org/traccar/notificators/Notificator.java b/src/org/traccar/notificators/Notificator.java deleted file mode 100644 index 5e40971c6..000000000 --- a/src/org/traccar/notificators/Notificator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.notificators; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.notification.MessageException; - -public abstract class Notificator { - - private static final Logger LOGGER = LoggerFactory.getLogger(Notificator.class); - - public void sendAsync(final long userId, final Event event, final Position position) { - new Thread(new Runnable() { - public void run() { - try { - sendSync(userId, event, position); - } catch (MessageException | InterruptedException error) { - LOGGER.warn("Event send error", error); - } - } - }).start(); - } - - public abstract void sendSync(long userId, Event event, Position position) - throws MessageException, InterruptedException; - -} diff --git a/src/org/traccar/notificators/NotificatorFirebase.java b/src/org/traccar/notificators/NotificatorFirebase.java deleted file mode 100644 index 75d325de2..000000000 --- a/src/org/traccar/notificators/NotificatorFirebase.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.notificators; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.model.User; -import org.traccar.notification.NotificationFormatter; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; - -public class NotificatorFirebase extends Notificator { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); - - private static final String URL = "https://fcm.googleapis.com/fcm/send"; - - private String key; - - public static class Notification { - @JsonProperty("body") - private String body; - } - - public static class Message { - @JsonProperty("registration_ids") - private String[] tokens; - @JsonProperty("notification") - private Notification notification; - } - - public NotificatorFirebase() { - key = Context.getConfig().getString("notificator.firebase.key"); - } - - @Override - public void sendSync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); - if (user.getAttributes().containsKey("notificationTokens")) { - - Notification notification = new Notification(); - notification.body = NotificationFormatter.formatShortMessage(userId, event, position).trim(); - - Message message = new Message(); - message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; - - Context.getClient().target(URL).request() - .header("Authorization", "key=" + key) - .async().post(Entity.json(message), new InvocationCallback<Object>() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Firebase notification error", throwable); - } - }); - } - } - - @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); - } - -} diff --git a/src/org/traccar/notificators/NotificatorMail.java b/src/org/traccar/notificators/NotificatorMail.java deleted file mode 100644 index 6b9774c58..000000000 --- a/src/org/traccar/notificators/NotificatorMail.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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.notificators; - -import org.traccar.Context; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.notification.FullMessage; -import org.traccar.notification.MessageException; -import org.traccar.notification.NotificationFormatter; - -import javax.mail.MessagingException; - -public final class NotificatorMail extends Notificator { - - @Override - public void sendSync(long userId, Event event, Position position) throws MessageException { - try { - FullMessage message = NotificationFormatter.formatFullMessage(userId, event, position); - Context.getMailManager().sendMessage(userId, message.getSubject(), message.getBody()); - } catch (MessagingException e) { - throw new MessageException(e); - } - } - -} diff --git a/src/org/traccar/notificators/NotificatorNull.java b/src/org/traccar/notificators/NotificatorNull.java deleted file mode 100644 index 9364336be..000000000 --- a/src/org/traccar/notificators/NotificatorNull.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.notificators; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.Event; -import org.traccar.model.Position; - -public final class NotificatorNull extends Notificator { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); - - @Override - public void sendAsync(long userId, Event event, Position position) { - LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); - } - - @Override - public void sendSync(long userId, Event event, Position position) { - LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); - } - -} diff --git a/src/org/traccar/notificators/NotificatorSms.java b/src/org/traccar/notificators/NotificatorSms.java deleted file mode 100644 index d5c791eae..000000000 --- a/src/org/traccar/notificators/NotificatorSms.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2017 - 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. - * 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.notificators; - -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.StatisticsManager; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.model.User; -import org.traccar.notification.MessageException; -import org.traccar.notification.NotificationFormatter; -import org.traccar.sms.SmsManager; - -public final class NotificatorSms extends Notificator { - - private final SmsManager smsManager; - - public NotificatorSms() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - final String smsClass = Context.getConfig().getString("notificator.sms.manager.class", ""); - if (smsClass.length() > 0) { - smsManager = (SmsManager) Class.forName(smsClass).newInstance(); - } else { - smsManager = Context.getSmsManager(); - } - } - - @Override - public void sendAsync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); - if (user.getPhone() != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - smsManager.sendMessageAsync(user.getPhone(), - NotificationFormatter.formatShortMessage(userId, event, position), false); - } - } - - @Override - public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { - final User user = Context.getPermissionsManager().getUser(userId); - if (user.getPhone() != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - smsManager.sendMessageSync(user.getPhone(), - NotificationFormatter.formatShortMessage(userId, event, position), false); - } - } - -} diff --git a/src/org/traccar/notificators/NotificatorWeb.java b/src/org/traccar/notificators/NotificatorWeb.java deleted file mode 100644 index 1d11c0b46..000000000 --- a/src/org/traccar/notificators/NotificatorWeb.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.notificators; - -import org.traccar.Context; -import org.traccar.model.Event; -import org.traccar.model.Position; - -public final class NotificatorWeb extends Notificator { - - @Override - public void sendSync(long userId, Event event, Position position) { - Context.getConnectionManager().updateEvent(userId, event); - } - -} diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java deleted file mode 100644 index 08f932ceb..000000000 --- a/src/org/traccar/protocol/AdmProtocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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 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; - -public class AdmProtocol extends BaseProtocol { - - public AdmProtocol() { - setSupportedDataCommands( - Command.TYPE_GET_DEVICE_STATUS, - Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 1, -3, 0, true)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AdmProtocolEncoder()); - pipeline.addLast(new AdmProtocolDecoder(AdmProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java deleted file mode 100644 index 52d1439ed..000000000 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class AdmProtocolDecoder extends BaseProtocolDecoder { - - public AdmProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int CMD_RESPONSE_SIZE = 0x84; - public static final int MSG_IMEI = 0x03; - public static final int MSG_PHOTO = 0x0A; - public static final int MSG_ADM5 = 0x01; - - private Position decodeData(Channel channel, SocketAddress remoteAddress, ByteBuf buf, int type) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (BitUtil.to(type, 2) == 0) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); - - int status = buf.readUnsignedShortLE(); - position.set(Position.KEY_STATUS, status); - position.setValid(!BitUtil.check(status, 5)); - 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.readShortLE()); - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f); - - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - - 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 - buf.readUnsignedByte(); // vib_count - - int out = buf.readUnsignedByte(); - for (int i = 0; i <= 3; i++) { - position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(out, i) ? 1 : 0); - } - - buf.readUnsignedByte(); // in_alarm - } - - if (BitUtil.check(type, 3)) { - for (int i = 1; i <= 6; i++) { - 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.readUnsignedIntLE()); - } - } - - if (BitUtil.check(type, 5)) { - for (int i = 1; i <= 3; i++) { - buf.readUnsignedShortLE(); // fuel level - } - for (int i = 1; i <= 3; i++) { - position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte()); - } - } - - if (BitUtil.check(type, 6)) { - int endIndex = buf.readerIndex() + buf.readUnsignedByte(); - while (buf.readerIndex() < endIndex) { - int mask = buf.readUnsignedByte(); - long value; - switch (BitUtil.from(mask, 6)) { - case 3: - value = buf.readLongLE(); - break; - case 2: - value = buf.readUnsignedIntLE(); - break; - case 1: - value = buf.readUnsignedShortLE(); - break; - default: - value = buf.readUnsignedByte(); - break; - } - int index = BitUtil.to(mask, 6); - switch (index) { - case 1: - position.set(Position.PREFIX_TEMP + 1, value); - break; - case 2: - position.set("humidity", value); - break; - case 3: - position.set("illumination", value); - break; - case 4: - position.set(Position.KEY_BATTERY, value); - break; - default: - position.set("can" + index, value); - break; - } - } - } - - if (BitUtil.check(type, 7)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - } - - return position; - } - - return null; - } - - private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - int responseTextLength = buf.bytesBefore((byte) 0); - if (responseTextLength < 0) { - responseTextLength = CMD_RESPONSE_SIZE - 3; - } - 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 { - ByteBuf buf = (ByteBuf) msg; - - 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.readSlice(15).toString(StandardCharsets.UTF_8)); - } else { - return decodeData(channel, remoteAddress, buf, type); - } - } else { - return parseCommandResponse(channel, remoteAddress, buf); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java deleted file mode 100644 index e76bc2ddc..000000000 --- a/src/org/traccar/protocol/AdmProtocolEncoder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com) - * - * 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.model.Command; - -public class AdmProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_GET_DEVICE_STATUS: - return formatCommand(command, "STATUS\r\n"); - - case Command.TYPE_CUSTOM: - return formatCommand(command, "{%s}\r\n", Command.KEY_DATA); - - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/AisProtocol.java b/src/org/traccar/protocol/AisProtocol.java deleted file mode 100644 index 3b9cad7c8..000000000 --- a/src/org/traccar/protocol/AisProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class AisProtocol extends BaseProtocol { - - public AisProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new AisProtocolDecoder(AisProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AisProtocolDecoder.java b/src/org/traccar/protocol/AisProtocolDecoder.java deleted file mode 100644 index 8970f3d4a..000000000 --- a/src/org/traccar/protocol/AisProtocolDecoder.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitBuffer; -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.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -public class AisProtocolDecoder extends BaseProtocolDecoder { - - public AisProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("!AIVDM,") - .number("(d+),") // count - .number("(d+),") // index - .number("(d+)?,") // id - .expression(".,") // radio channel - .expression("([^,]+),") // payload - .any() - .compile(); - - private Position decodePayload(Channel channel, SocketAddress remoteAddress, BitBuffer buf) { - - int type = buf.readUnsigned(6); - if (type == 1 || type == 2 || type == 3 || type == 18) { - - buf.readUnsigned(2); - int mmsi = buf.readUnsigned(30); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(mmsi)); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date()); - - if (type == 18) { - buf.readUnsigned(8); // reserved - } else { - position.set(Position.KEY_STATUS, buf.readUnsigned(4)); - position.set("turn", buf.readSigned(8)); - } - - position.setSpeed(buf.readUnsigned(10) * 0.1); - position.setValid(buf.readUnsigned(1) != 0); - position.setLongitude(buf.readSigned(28) * 0.0001 / 60.0); - position.setLatitude(buf.readSigned(27) * 0.0001 / 60.0); - position.setCourse(buf.readUnsigned(12) * 0.1); - - position.set("heading", buf.readUnsigned(9)); - - return position; - - } - - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String[] sentences = ((String) msg).split("\\r\\n"); - - List<Position> positions = new ArrayList<>(); - Map<Integer, BitBuffer> buffers = new HashMap<>(); - - for (String sentence : sentences) { - if (!sentence.isEmpty()) { - Parser parser = new Parser(PATTERN, sentence); - if (parser.matches()) { - - int count = parser.nextInt(0); - int index = parser.nextInt(0); - int id = parser.nextInt(0); - - Position position = null; - - if (count == 1) { - BitBuffer bits = new BitBuffer(); - bits.writeEncoded(parser.next().getBytes(StandardCharsets.US_ASCII)); - position = decodePayload(channel, remoteAddress, bits); - } else { - BitBuffer bits = buffers.get(id); - if (bits == null) { - bits = new BitBuffer(); - buffers.put(id, bits); - } - bits.writeEncoded(parser.next().getBytes(StandardCharsets.US_ASCII)); - if (count == index) { - position = decodePayload(channel, remoteAddress, bits); - buffers.remove(id); - } - } - - if (position != null) { - positions.add(position); - } - - } - } - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/AlematicsFrameDecoder.java b/src/org/traccar/protocol/AlematicsFrameDecoder.java deleted file mode 100644 index be7666657..000000000 --- a/src/org/traccar/protocol/AlematicsFrameDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.LineBasedFrameDecoder; -import org.traccar.NetworkMessage; - -public class AlematicsFrameDecoder extends LineBasedFrameDecoder { - - private static final int MESSAGE_MINIMUM_LENGTH = 2; - - public AlematicsFrameDecoder(int maxFrameLength) { - super(maxFrameLength); - } - - // example of heartbeat: FA F8 00 07 00 03 15 AD 4E 78 3A D2 - - @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - if (buf.getUnsignedShort(buf.readerIndex()) == 0xFAF8) { - ByteBuf heartbeat = buf.readRetainedSlice(12); - if (ctx != null && ctx.channel() != null) { - ctx.channel().writeAndFlush(new NetworkMessage(heartbeat, ctx.channel().remoteAddress())); - } - } - - return super.decode(ctx, buf); - } - -} diff --git a/src/org/traccar/protocol/AlematicsProtocol.java b/src/org/traccar/protocol/AlematicsProtocol.java deleted file mode 100644 index 8da2356b9..000000000 --- a/src/org/traccar/protocol/AlematicsProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class AlematicsProtocol extends BaseProtocol { - - public AlematicsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AlematicsFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new AlematicsProtocolDecoder(AlematicsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/org/traccar/protocol/AlematicsProtocolDecoder.java deleted file mode 100644 index 25ccf6856..000000000 --- a/src/org/traccar/protocol/AlematicsProtocolDecoder.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.regex.Pattern; - -public class AlematicsProtocolDecoder extends BaseProtocolDecoder { - - public AlematicsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$T,") - .number("(d+),") // type - .number("(d+),") // index - .number("(d+),") // id - .number("(dddd)(dd)(dd)") // gps date - .number("(dd)(dd)(dd),") // gps time - .number("(dddd)(dd)(dd)") // device date - .number("(dd)(dd)(dd),") // device time - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(-?d+),") // altitude - .number("(d+.d),") // hdop - .number("(d+),") // satellites - .number("(d+),") // input - .number("(d+),") // output - .number("(d+.d+),") // adc - .number("(d+.d+),") // power - .number("(d+),") // odometer - .groupBegin() - .text("0,$S,") - .expression("(.*)") // text message - .or() - .number("(d+),") // extra mask - .expression("(.*)") // extra data - .or() - .any() - .groupEnd() - .compile(); - - private void decodeExtras(Position position, Parser parser) { - - int mask = parser.nextInt(); - String[] data = parser.next().split(","); - - int index = 0; - - if (BitUtil.check(mask, 0)) { - index++; // pulse counter 3 - } - - if (BitUtil.check(mask, 1)) { - position.set(Position.KEY_POWER, Integer.parseInt(data[index++])); - } - - if (BitUtil.check(mask, 2)) { - position.set(Position.KEY_BATTERY, Integer.parseInt(data[index++])); - } - - if (BitUtil.check(mask, 3)) { - position.set(Position.KEY_OBD_SPEED, Integer.parseInt(data[index++])); - } - - if (BitUtil.check(mask, 4)) { - position.set(Position.KEY_RPM, Integer.parseInt(data[index++])); - } - - if (BitUtil.check(mask, 5)) { - position.set(Position.KEY_RSSI, Integer.parseInt(data[index++])); - } - - if (BitUtil.check(mask, 6)) { - index++; // pulse counter 2 - } - - if (BitUtil.check(mask, 7)) { - index++; // magnetic rotation sensor rpm - } - - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - position.set(Position.KEY_TYPE, parser.nextInt()); - position.set(Position.KEY_INDEX, parser.nextInt()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setFixTime(parser.nextDateTime()); - position.setDeviceTime(parser.nextDateTime()); - - position.setValid(true); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - position.setAltitude(parser.nextInt(0)); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_INPUT, parser.nextInt()); - position.set(Position.KEY_OUTPUT, parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextInt()); - - if (parser.hasNext()) { - position.set("text", parser.next()); - } else if (parser.hasNext()) { - decodeExtras(position, parser); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/AnytrekProtocol.java b/src/org/traccar/protocol/AnytrekProtocol.java deleted file mode 100644 index 4ab5833f7..000000000 --- a/src/org/traccar/protocol/AnytrekProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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; - -public class AnytrekProtocol extends BaseProtocol { - - public AnytrekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); - pipeline.addLast(new AnytrekProtocolDecoder(AnytrekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AnytrekProtocolDecoder.java b/src/org/traccar/protocol/AnytrekProtocolDecoder.java deleted file mode 100644 index c48f59c90..000000000 --- a/src/org/traccar/protocol/AnytrekProtocolDecoder.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class AnytrekProtocolDecoder extends BaseProtocolDecoder { - - public AnytrekProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void sendResponse(Channel channel, SocketAddress remoteAddress, int type) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(0x7878); - response.writeShortLE(1 + 1 + 2 + 1 + 2); // length - response.writeByte(type); - response.writeByte(0); // error - response.writeShortLE(0); // report interval - response.writeByte(0); // clear alarm - response.writeShortLE(0); // checksum - response.writeByte('\r'); - response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedShortLE(); // size - int type = buf.readUnsignedByte(); - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(2); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_FW, buf.readUnsignedShortLE()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_SATELLITES, BitUtil.to(buf.readUnsignedByte(), 4)); - - double latitude = buf.readUnsignedIntLE() / 1800000.0; - double longitude = buf.readUnsignedIntLE() / 1800000.0; - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - int flags = buf.readUnsignedShortLE(); - position.setCourse(BitUtil.to(flags, 10)); - position.setValid(BitUtil.check(flags, 12)); - - if (!BitUtil.check(flags, 10)) { - latitude = -latitude; - } - if (BitUtil.check(flags, 11)) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - - buf.readUnsignedIntLE(); // info index - buf.readUnsignedIntLE(); // setting index - - flags = buf.readUnsignedByte(); - position.set(Position.KEY_CHARGE, BitUtil.check(flags, 0)); - position.set(Position.KEY_IGNITION, BitUtil.check(flags, 1)); - position.set(Position.KEY_ALARM, BitUtil.check(flags, 4) ? Position.ALARM_GENERAL : null); - - buf.readUnsignedShortLE(); // charge current - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - - sendResponse(channel, remoteAddress, type); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ApelProtocol.java b/src/org/traccar/protocol/ApelProtocol.java deleted file mode 100644 index 382aa16af..000000000 --- a/src/org/traccar/protocol/ApelProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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; -public class ApelProtocol extends BaseProtocol { - - public ApelProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); - pipeline.addLast(new ApelProtocolDecoder(ApelProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ApelProtocolDecoder.java b/src/org/traccar/protocol/ApelProtocolDecoder.java deleted file mode 100644 index c95a0366a..000000000 --- a/src/org/traccar/protocol/ApelProtocolDecoder.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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. - * 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.Protocol; -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; - -public class ApelProtocolDecoder extends BaseProtocolDecoder { - - private long lastIndex; - private long newIndex; - - public ApelProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final short MSG_NULL = 0; - public static final short MSG_REQUEST_TRACKER_ID = 10; - public static final short MSG_TRACKER_ID = 11; - public static final short MSG_TRACKER_ID_EXT = 12; - public static final short MSG_DISCONNECT = 20; - public static final short MSG_REQUEST_PASSWORD = 30; - public static final short MSG_PASSWORD = 31; - public static final short MSG_REQUEST_STATE_FULL_INFO = 90; - public static final short MSG_STATE_FULL_INFO_T104 = 92; - public static final short MSG_REQUEST_CURRENT_GPS_DATA = 100; - public static final short MSG_CURRENT_GPS_DATA = 101; - public static final short MSG_REQUEST_SENSORS_STATE = 110; - public static final short MSG_SENSORS_STATE = 111; - public static final short MSG_SENSORS_STATE_T100 = 112; - public static final short MSG_SENSORS_STATE_T100_4 = 113; - public static final short MSG_REQUEST_LAST_LOG_INDEX = 120; - public static final short MSG_LAST_LOG_INDEX = 121; - public static final short MSG_REQUEST_LOG_RECORDS = 130; - public static final short MSG_LOG_RECORDS = 131; - public static final short MSG_EVENT = 141; - public static final short MSG_TEXT = 150; - public static final short MSG_ACK_ALARM = 160; - public static final short MSG_SET_TRACKER_MODE = 170; - public static final short MSG_GPRS_COMMAND = 180; - - private void sendSimpleMessage(Channel channel, short type) { - 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) { - 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())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - int type = buf.readUnsignedShortLE(); - boolean alarm = (type & 0x8000) != 0; - type = type & 0x7FFF; - buf.readUnsignedShortLE(); // length - - if (alarm) { - sendSimpleMessage(channel, MSG_ACK_ALARM); - } - - if (type == MSG_TRACKER_ID) { - return null; // unsupported authentication type - } - - if (type == MSG_TRACKER_ID_EXT) { - - buf.readUnsignedIntLE(); // id - int length = buf.readUnsignedShortLE(); - buf.skipBytes(length); - length = buf.readUnsignedShortLE(); - getDeviceSession(channel, remoteAddress, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); - - } else if (type == MSG_LAST_LOG_INDEX) { - - long index = buf.readUnsignedIntLE(); - if (index > 0) { - newIndex = index; - requestArchive(channel); - } - - } else if (type == MSG_CURRENT_GPS_DATA || type == MSG_STATE_FULL_INFO_T104 || type == MSG_LOG_RECORDS) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - int recordCount = 1; - if (type == MSG_LOG_RECORDS) { - recordCount = buf.readUnsignedShortLE(); - } - - for (int j = 0; j < recordCount; j++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int subtype = type; - if (type == MSG_LOG_RECORDS) { - position.set(Position.KEY_ARCHIVE, true); - lastIndex = buf.readUnsignedIntLE() + 1; - position.set(Position.KEY_INDEX, lastIndex); - - subtype = buf.readUnsignedShortLE(); - if (subtype != MSG_CURRENT_GPS_DATA && subtype != MSG_STATE_FULL_INFO_T104) { - buf.skipBytes(buf.readUnsignedShortLE()); - continue; - } - buf.readUnsignedShortLE(); // length - } - - 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(); - position.setValid(speed != 255); - position.setSpeed(UnitsConverter.knotsFromKph(speed)); - position.set(Position.KEY_HDOP, buf.readByte()); - } else { - int speed = buf.readShortLE(); - position.setValid(speed != -1); - position.setSpeed(UnitsConverter.knotsFromKph(speed * 0.01)); - } - - 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.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.readUnsignedShortLE()); - } - - 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.readUnsignedIntLE(); // crc - - if (type == MSG_LOG_RECORDS) { - requestArchive(channel); - } else { - sendSimpleMessage(channel, MSG_REQUEST_LAST_LOG_INDEX); - } - - return positions; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AplicomFrameDecoder.java b/src/org/traccar/protocol/AplicomFrameDecoder.java deleted file mode 100644 index 6e81e8202..000000000 --- a/src/org/traccar/protocol/AplicomFrameDecoder.java +++ /dev/null @@ -1,62 +0,0 @@ -/*
- * Copyright 2013 Anton Tananaev (anton@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 AplicomFrameDecoder extends BaseFrameDecoder {
-
- @Override
- protected Object decode(
- ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
-
- // Skip Alive message
- while (buf.isReadable() && Character.isDigit(buf.getByte(buf.readerIndex()))) {
- buf.readByte();
- }
-
- // Check minimum length
- if (buf.readableBytes() < 11) {
- return null;
- }
-
- // Read flags
- int version = buf.getUnsignedByte(buf.readerIndex() + 1);
- int offset = 1 + 1 + 3;
- if ((version & 0x80) != 0) {
- offset += 4;
- }
-
- // Get data length
- int length = buf.getUnsignedShort(buf.readerIndex() + offset);
- offset += 2;
- if ((version & 0x40) != 0) {
- offset += 3;
- }
- length += offset; // add header
-
- // Return buffer
- if (buf.readableBytes() >= length) {
- return buf.readRetainedSlice(length);
- }
-
- return null;
- }
-
-}
diff --git a/src/org/traccar/protocol/AplicomProtocol.java b/src/org/traccar/protocol/AplicomProtocol.java deleted file mode 100644 index 2b9dbf97c..000000000 --- a/src/org/traccar/protocol/AplicomProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class AplicomProtocol extends BaseProtocol { - - public AplicomProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AplicomFrameDecoder()); - pipeline.addLast(new AplicomProtocolDecoder(AplicomProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java deleted file mode 100644 index 215aa0211..000000000 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ /dev/null @@ -1,702 +0,0 @@ -/* - * 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. - * 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.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.ArrayList; -import java.util.Date; - -public class AplicomProtocolDecoder extends BaseProtocolDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(AplicomProtocolDecoder.class); - - public AplicomProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final long IMEI_BASE_TC65_V20 = 0x1437207000000L; - private static final long IMEI_BASE_TC65_V28 = 358244010000000L; - private static final long IMEI_BASE_TC65I_V11 = 0x14143B4000000L; - - private static boolean validateImei(long imei) { - return Checksum.luhn(imei / 10) == imei % 10; - } - - private static long imeiFromUnitId(long unitId) { - - if (unitId == 0) { - - return 0; - - } else { - - // Try TC65i - long imei = IMEI_BASE_TC65I_V11 + unitId; - if (validateImei(imei)) { - return imei; - } - - // Try TC65 v2.8 - imei = IMEI_BASE_TC65_V28 + ((unitId + 0xA8180) & 0xFFFFFF); - if (validateImei(imei)) { - return imei; - } - - // Try TC65 v2.0 - imei = IMEI_BASE_TC65_V20 + unitId; - if (validateImei(imei)) { - return imei; - } - - } - - return unitId; - } - - private static final int DEFAULT_SELECTOR_D = 0x0002fC; - private static final int DEFAULT_SELECTOR_E = 0x007ffc; - private static final int DEFAULT_SELECTOR_F = 0x0007fd; - - private static final int EVENT_DATA = 119; - - private void decodeEventData(Position position, ByteBuf buf, int event) { - switch (event) { - case 2: - case 40: - buf.readUnsignedByte(); - break; - case 9: - buf.readUnsignedMedium(); - break; - case 31: - case 32: - buf.readUnsignedShort(); - break; - case 38: - buf.skipBytes(4 * 9); - break; - case 113: - buf.readUnsignedInt(); - buf.readUnsignedByte(); - break; - case 119: - position.set("eventData", ByteBufUtil.hexDump( - buf, buf.readerIndex(), Math.min(buf.readableBytes(), 1024))); - break; - case 121: - case 142: - buf.readLong(); - break; - case 130: - buf.readUnsignedInt(); // incorrect - break; - case 188: - decodeEB(position, buf); - break; - default: - break; - } - } - - private void decodeCanData(ByteBuf buf, Position position) { - - buf.readUnsignedMedium(); // packet identifier - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - int count = buf.readUnsignedByte(); - buf.readUnsignedByte(); // batch count - buf.readUnsignedShort(); // selector bit - buf.readUnsignedInt(); // timestamp - - buf.skipBytes(8); - - ArrayList<ByteBuf> values = new ArrayList<>(count); - - for (int i = 0; i < count; i++) { - values.add(buf.readSlice(8)); - } - - for (int i = 0; i < count; i++) { - ByteBuf value = values.get(i); - switch (buf.readInt()) { - case 0x20D: - 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", ByteBufUtil.hexDump(value)); - break; - case 0x40C: - position.set("airTempDep1", value.readShortLE() * 0.1); - position.set("airTempDep2", value.readShortLE() * 0.1); - break; - case 0x40D: - position.set("coldUnitState", ByteBufUtil.hexDump(value)); - break; - case 0x50C: - position.set("defrostTempDep1", value.readShortLE() * 0.1); - position.set("defrostTempDep2", value.readShortLE() * 0.1); - break; - case 0x50D: - 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", value.readIntLE() * 0.1); - break; - case 0x02: - position.set("setpointZone2", value.readIntLE() * 0.1); - break; - case 0x05: - position.set("unitType", value.readIntLE()); - break; - case 0x13: - position.set("dieselHours", value.readIntLE() / 60 / 60); - break; - case 0x14: - position.set("electricHours", value.readIntLE() / 60 / 60); - break; - case 0x17: - position.set("serviceIndicator", value.readIntLE()); - break; - case 0x18: - position.set("softwareVersion", value.readIntLE() * 0.01); - break; - default: - break; - } - break; - default: - LOGGER.warn("Aplicom CAN decoding error", new UnsupportedOperationException()); - break; - } - } - } - - private void decodeD(Position position, ByteBuf buf, int selector, int event) { - - if ((selector & 0x0008) != 0) { - position.setValid((buf.readUnsignedByte() & 0x40) != 0); - } else { - getLastLocation(position, null); - } - - if ((selector & 0x0004) != 0) { - position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000)); - } - - if ((selector & 0x0008) != 0) { - position.setFixTime(new Date(buf.readUnsignedInt() * 1000)); - if (position.getDeviceTime() == null) { - position.setDeviceTime(position.getFixTime()); - } - position.setLatitude(buf.readInt() / 1000000.0); - position.setLongitude(buf.readInt() / 1000000.0); - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - } - - if ((selector & 0x0010) != 0) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.set("maximumSpeed", buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedByte() * 2.0); - } - - if ((selector & 0x0040) != 0) { - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - } - - if ((selector & 0x0020) != 0) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShort()); - } - - if ((selector & 0x8000) != 0) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - } - - // Pulse rate 1 - if ((selector & 0x10000) != 0) { - buf.readUnsignedShort(); - buf.readUnsignedInt(); - } - - // Pulse rate 2 - if ((selector & 0x20000) != 0) { - buf.readUnsignedShort(); - buf.readUnsignedInt(); - } - - if ((selector & 0x0080) != 0) { - position.set("trip1", buf.readUnsignedInt()); - } - - if ((selector & 0x0100) != 0) { - position.set("trip2", buf.readUnsignedInt()); - } - - if ((selector & 0x0040) != 0) { - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - } - - if ((selector & 0x0200) != 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, - String.valueOf(((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); - } - - if ((selector & 0x0400) != 0) { - buf.readUnsignedByte(); // Keypad - } - - if ((selector & 0x0800) != 0) { - position.setAltitude(buf.readShort()); - } - - if ((selector & 0x2000) != 0) { - buf.readUnsignedShort(); // snapshot counter - } - - if ((selector & 0x4000) != 0) { - buf.skipBytes(8); // state flags - } - - if ((selector & 0x80000) != 0) { - buf.skipBytes(11); // cell info - } - - if ((selector & 0x1000) != 0) { - decodeEventData(position, buf, event); - } - - if (Context.getConfig().getBoolean(getProtocolName() + ".can") - && buf.isReadable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { - decodeCanData(buf, position); - } - } - - private void decodeE(Position position, ByteBuf buf, int selector) { - - if ((selector & 0x0008) != 0) { - position.set("tachographEvent", buf.readUnsignedShort()); - } - - if ((selector & 0x0004) != 0) { - getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); - } else { - getLastLocation(position, null); - } - - if ((selector & 0x0010) != 0) { - String time = buf.readUnsignedByte() + "s " + buf.readUnsignedByte() + "m " + buf.readUnsignedByte() + "h " - + buf.readUnsignedByte() + "M " + buf.readUnsignedByte() + "D " + buf.readUnsignedByte() + "Y " - + buf.readByte() + "m " + buf.readByte() + "h"; - position.set("tachographTime", time); - } - - position.set("workState", buf.readUnsignedByte()); - position.set("driver1State", buf.readUnsignedByte()); - position.set("driver2State", buf.readUnsignedByte()); - - if ((selector & 0x0020) != 0) { - position.set("tachographStatus", buf.readUnsignedByte()); - } - - if ((selector & 0x0040) != 0) { - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0); - } - - if ((selector & 0x0080) != 0) { - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); - } - - if ((selector & 0x0100) != 0) { - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5); - } - - if ((selector & 0x8000) != 0) { - position.set("kFactor", buf.readUnsignedShort() * 0.001 + " pulses/m"); - } - - if ((selector & 0x0200) != 0) { - position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); - } - - if ((selector & 0x0400) != 0) { - position.set("extraInfo", buf.readUnsignedShort()); - } - - if ((selector & 0x0800) != 0) { - 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.readSlice(20).toString(StandardCharsets.US_ASCII).trim(); - if (!card.isEmpty()) { - position.set("card1", card); - } - } - - if ((selector & 0x4000) != 0) { - buf.readUnsignedByte(); // card 2 type - buf.readUnsignedByte(); // card 2 country code - String card = buf.readSlice(20).toString(StandardCharsets.US_ASCII).trim(); - if (!card.isEmpty()) { - position.set("card2", card); - } - } - - if ((selector & 0x10000) != 0) { - int count = buf.readUnsignedByte(); - for (int i = 1; i <= count; i++) { - position.set("driver" + i, buf.readSlice(22).toString(StandardCharsets.US_ASCII).trim()); - position.set("driverTime" + i, buf.readUnsignedInt()); - } - } - } - - private void decodeH(Position position, ByteBuf buf, int selector) { - - if ((selector & 0x0004) != 0) { - getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); - } else { - getLastLocation(position, null); - } - - if ((selector & 0x0040) != 0) { - buf.readUnsignedInt(); // reset time - } - - if ((selector & 0x2000) != 0) { - buf.readUnsignedShort(); // snapshot counter - } - - int index = 1; - while (buf.readableBytes() > 0) { - - position.set("h" + index + "Index", buf.readUnsignedByte()); - - buf.readUnsignedShort(); // length - - int n = buf.readUnsignedByte(); - int m = buf.readUnsignedByte(); - - position.set("h" + index + "XLength", n); - position.set("h" + index + "YLength", m); - - if ((selector & 0x0008) != 0) { - position.set("h" + index + "XType", buf.readUnsignedByte()); - position.set("h" + index + "YType", buf.readUnsignedByte()); - position.set("h" + index + "Parameters", buf.readUnsignedByte()); - } - - boolean percentageFormat = (selector & 0x0020) != 0; - - StringBuilder data = new StringBuilder(); - for (int i = 0; i < n * m; i++) { - if (percentageFormat) { - data.append(buf.readUnsignedByte() * 0.5).append("%").append(" "); - } else { - data.append(buf.readUnsignedShort()).append(" "); - } - } - - position.set("h" + index + "Data", data.toString().trim()); - - position.set("h" + index + "Total", buf.readUnsignedInt()); - - if ((selector & 0x0010) != 0) { - int k = buf.readUnsignedByte(); - - data = new StringBuilder(); - for (int i = 1; i < n; i++) { - if (k == 1) { - data.append(buf.readByte()).append(" "); - } else if (k == 2) { - data.append(buf.readShort()).append(" "); - } - } - position.set("h" + index + "XLimits", data.toString().trim()); - - data = new StringBuilder(); - for (int i = 1; i < m; i++) { - if (k == 1) { - data.append(buf.readByte()).append(" "); - } else if (k == 2) { - data.append(buf.readShort()).append(" "); - } - } - position.set("h" + index + "YLimits", data.toString().trim()); - } - - index += 1; - } - } - - private void decodeEB(Position position, ByteBuf buf) { - - if (buf.readByte() != (byte) 'E' || buf.readByte() != (byte) 'B') { - return; - } - - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - position.set("dataValidity", buf.readUnsignedByte()); - position.set("towed", buf.readUnsignedByte()); - buf.readUnsignedShort(); // length - - while (buf.readableBytes() > 0) { - buf.readUnsignedByte(); // towed position - int type = buf.readUnsignedByte(); - int length = buf.readUnsignedByte(); - int end = buf.readerIndex() + length; - - switch (type) { - case 0x01: - position.set("brakeFlags", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x02: - position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); - position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); - position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); - position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); - break; - case 0x03: - position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedShort() * 2); - break; - case 0x04: - position.set("tyrePressure", buf.readUnsignedByte() * 10); - position.set("pneumaticPressure", buf.readUnsignedByte() * 5); - break; - case 0x05: - position.set("brakeLining", buf.readUnsignedByte() * 0.4); - position.set("brakeTemperature", buf.readUnsignedByte() * 10); - break; - case 0x06: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5L); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5L); - position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5L); - break; - case 0x0A: - position.set("absStatusCounter", buf.readUnsignedShort()); - position.set("atvbStatusCounter", buf.readUnsignedShort()); - position.set("vdcActiveCounter", buf.readUnsignedShort()); - break; - case 0x0B: - position.set("brakeMinMaxData", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x0C: - position.set("missingPgn", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x0D: - buf.readUnsignedByte(); - position.set("towedDetectionStatus", buf.readUnsignedInt()); - buf.skipBytes(17); // vin - break; - case 0x0E: - default: - break; - } - - buf.readerIndex(end); - } - } - - private void decodeF(Position position, ByteBuf buf, int selector) { - - Date deviceTime = null; - - if ((selector & 0x0004) != 0) { - deviceTime = new Date(buf.readUnsignedInt() * 1000); - } - - getLastLocation(position, deviceTime); - - buf.readUnsignedByte(); // data validity - - if ((selector & 0x0008) != 0) { - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - position.set("rpmMax", buf.readUnsignedShort()); - position.set("rpmMin", buf.readUnsignedShort()); - } - - if ((selector & 0x0010) != 0) { - position.set("engineTemp", buf.readShort()); - position.set("engineTempMax", buf.readShort()); - position.set("engineTempMin", buf.readShort()); - } - - if ((selector & 0x0020) != 0) { - 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()); - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - } - - if ((selector & 0x0040) != 0) { - position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt()); - } - - if ((selector & 0x0080) != 0) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - - if ((selector & 0x0100) != 0) { - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - position.set("speedMax", buf.readUnsignedByte()); - position.set("speedMin", buf.readUnsignedByte()); - position.set("hardBraking", buf.readUnsignedByte()); - } - - if ((selector & 0x0200) != 0) { - position.set("tachographSpeed", buf.readUnsignedByte()); - position.set("driver1State", buf.readUnsignedByte()); - position.set("driver2State", buf.readUnsignedByte()); - position.set("tachographStatus", buf.readUnsignedByte()); - 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 { - - ByteBuf buf = (ByteBuf) msg; - - char protocol = (char) buf.readByte(); - int version = buf.readUnsignedByte(); - - String imei; - if ((version & 0x80) != 0) { - imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium()); - } else { - imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium())); - } - - buf.readUnsignedShort(); // length - - int selector = DEFAULT_SELECTOR_D; - if (protocol == 'E') { - selector = DEFAULT_SELECTOR_E; - } else if (protocol == 'F') { - selector = DEFAULT_SELECTOR_F; - } - if ((version & 0x40) != 0) { - selector = buf.readUnsignedMedium(); - } - - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - int event = buf.readUnsignedByte(); - position.set(Position.KEY_EVENT, event); - position.set("eventInfo", buf.readUnsignedByte()); - - if (protocol == 'D') { - decodeD(position, buf, selector, event); - } else if (protocol == 'E') { - decodeE(position, buf, selector); - } else if (protocol == 'H') { - decodeH(position, buf, selector); - } else if (protocol == 'F') { - decodeF(position, buf, selector); - } else { - return null; - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/AppelloProtocol.java b/src/org/traccar/protocol/AppelloProtocol.java deleted file mode 100644 index 1ca4168e4..000000000 --- a/src/org/traccar/protocol/AppelloProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class AppelloProtocol extends BaseProtocol { - - public AppelloProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AppelloProtocolDecoder(AppelloProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AppelloProtocolDecoder.java b/src/org/traccar/protocol/AppelloProtocolDecoder.java deleted file mode 100644 index 47e329234..000000000 --- a/src/org/traccar/protocol/AppelloProtocolDecoder.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class AppelloProtocolDecoder extends BaseProtocolDecoder { - - public AppelloProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("FOLLOWIT,") // brand - .number("(d+),") // imei - .groupBegin() - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .or() - .text("UTCTIME,") - .groupEnd() - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(-?d+),") // altitude - .expression("([FL]),") // gps state - .any() - .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; - } - - String imei = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (parser.hasNext(6)) { - position.setTime(parser.nextDateTime()); - } else { - getLastLocation(position, null); - } - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - - position.setAltitude(parser.nextDouble(0)); - - position.setValid(parser.next().equals("F")); - - return position; - } - -} diff --git a/src/org/traccar/protocol/AppletProtocol.java b/src/org/traccar/protocol/AppletProtocol.java deleted file mode 100644 index 2297dca03..000000000 --- a/src/org/traccar/protocol/AppletProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.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; - -public class AppletProtocol extends BaseProtocol { - - public AppletProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new AppletProtocolDecoder(AppletProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AppletProtocolDecoder.java b/src/org/traccar/protocol/AppletProtocolDecoder.java deleted file mode 100644 index 7a995cc24..000000000 --- a/src/org/traccar/protocol/AppletProtocolDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; - -import java.net.SocketAddress; - -public class AppletProtocolDecoder extends BaseHttpProtocolDecoder { - - public AppletProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, request.headers().get("From")); - if (deviceSession != null) { - sendResponse(channel, HttpResponseStatus.OK); - } else { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AquilaProtocol.java b/src/org/traccar/protocol/AquilaProtocol.java deleted file mode 100644 index 5ca1ec091..000000000 --- a/src/org/traccar/protocol/AquilaProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class AquilaProtocol extends BaseProtocol { - - public AquilaProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AquilaProtocolDecoder(AquilaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java deleted file mode 100644 index 57af5e366..000000000 --- a/src/org/traccar/protocol/AquilaProtocolDecoder.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 AquilaProtocolDecoder extends BaseProtocolDecoder { - - public AquilaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_A = new PatternBuilder() - .text("$$") - .expression("[^,]*,") // client - .number("(d+),") // device serial number - .number("(d+),") // event - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .groupBegin() - .number("(d+),") // gsm - .number("(d+),") // speed - .number("(d+),") // distance - .groupBegin() - .number("d+,") // driver code - .number("(d+),") // fuel - .number("([01]),") // io 1 - .number("[01],") // case open switch - .number("[01],") // over speed start - .number("[01],") // over speed end - .number("(?:d+,){3}") // reserved - .number("([01]),") // power status - .number("([01]),") // io 2 - .number("d+,") // reserved - .number("([01]),") // ignition - .number("[01],") // ignition off event - .number("(?:d+,){7}") // reserved - .number("[01],") // corner packet - .number("(?:d+,){8}") // reserved - .number("([01]),") // course bit 0 - .number("([01]),") // course bit 1 - .number("([01]),") // course bit 2 - .number("([01]),") // course bit 3 - .or() - .number("(d+),") // course - .number("(?:d+,){3}") // reserved - .number("[01],") // over speed start - .number("[01],") // over speed end - .number("(?:d+,){3}") // reserved - .number("([01]),") // power status - .number("(?:d+,){2}") // reserved - .number("[01],") // ignition on event - .number("([01]),") // ignition - .number("[01],") // ignition off event - .number("(?:d+,){5}") // reserved - .number("[01],") // low battery - .number("[01],") // corner packet - .number("(?:d+,){6}") // reserved - .number("[01],") // hard acceleration - .number("[01],") // hard braking - .number("[01],[01],[01],[01],") // course bits - .number("(d+),") // external voltage - .number("(d+),") // internal voltage - .number("(?:d+,){6}") // reserved - .expression("P([^,]+),") // obd - .expression("D([^,]+),") // dtcs - .number("-?d+,") // accelerometer x - .number("-?d+,") // accelerometer y - .number("-?d+,") // accelerometer z - .number("d+,") // delta distance - .or() - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+.d+),") // hdop - .number("(?:d+,){2}") // reserved - .number("(d+),") // adc 1 - .number("([01]),") // di 1 - .number("[01],") // case open - .number("[01],") // over speed start - .number("[01],") // over speed end - .number("(?:[01],){2}") // reserved - .number("[01],") // immobilizer - .number("([01]),") // power status - .number("([01]),") // di 2 - .number("(?:[01],){2}") // reserved - .number("([01]),") // ignition - .number("(?:[01],){6}") // reserved - .number("[01],") // low battery - .number("[01],") // corner packet - .number("(?:[01],){4}") // reserved - .number("[01],") // do 1 - .number("[01],") // reserved - .number("[01],") // hard acceleration - .number("[01],") // hard braking - .number("(?:[01],){4}") // reserved - .number("(d+),") // external voltage - .number("(d+),") // internal voltage - .groupEnd() - .or() - .number("(d+),") // sensor id - .expression("([^,]+),") // sensor data - .groupEnd() - .text("*") - .number("xx") // checksum - .compile(); - - private Position decodeA(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_A, 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()); - - position.set(Position.KEY_EVENT, parser.nextInt(0)); - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - - if (parser.hasNext(3)) { - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - } - - if (parser.hasNext(9)) { - - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.PREFIX_IN + 1, parser.next()); - position.set(Position.KEY_CHARGE, parser.next().equals("1")); - position.set(Position.PREFIX_IN + 2, parser.next()); - - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - - int course = (parser.nextInt(0) << 3) + (parser.nextInt(0) << 2) - + (parser.nextInt(0) << 1) + parser.nextInt(0); - if (course > 0 && course <= 8) { - position.setCourse((course - 1) * 45); - } - - } else if (parser.hasNext(7)) { - - position.setCourse(parser.nextInt(0)); - - position.set(Position.KEY_CHARGE, parser.next().equals("1")); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - position.set(Position.KEY_POWER, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - - String obd = parser.next(); - position.set("obd", obd.substring(1, obd.length() - 1)); - - String dtcs = parser.next(); - position.set(Position.KEY_DTCS, dtcs.substring(1, dtcs.length() - 1).replace('|', ' ')); - - } else if (parser.hasNext(10)) { - - position.setCourse(parser.nextInt(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - position.set(Position.PREFIX_IN + 1, parser.nextInt(0)); - position.set(Position.KEY_CHARGE, parser.next().equals("1")); - position.set(Position.PREFIX_IN + 2, parser.nextInt(0)); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - position.set(Position.KEY_POWER, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - - } else if (parser.hasNext(2)) { - - position.set("sensorId", parser.nextInt()); - position.set("sensorData", parser.next()); - - } - - return position; - } - - private static final Pattern PATTERN_B_1 = new PatternBuilder() - .text("$") - .expression("[^,]+,") // header - .expression("[^,]+,") // client - .expression("[^,]+,") // firmware version - .expression(".{2},") // packet 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 static final Pattern PATTERN_B_2 = new PatternBuilder() - .text("$") - .expression("[^,]+,") // header - .expression("[^,]+,") // client - .expression("(.{3}),") // message type - .number("(d+),") // imei - .expression(".{2},") // packet type - .number("(dd)(dd)(dddd)") // date (ddmmyyyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(-?d+.d+),") // latitude - .expression("([NS]),") - .number("(-?d+.d+),") // longitude - .expression("([EW]),") - .number("(-?d+.d+),") // altitude - .number("(d+.d+),") // speed - .any() - .compile(); - - private Position decodeB2(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_B_2, sentence); - if (!parser.matches()) { - return null; - } - - String type = parser.next(); - 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.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setAltitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - if (type.equals("EMR") && channel != null) { - String password = Context.getIdentityManager().lookupAttributeString( - deviceSession.getDeviceId(), getProtocolName() + ".password", "aquila123", true); - channel.writeAndFlush(new NetworkMessage( - "#set$" + id + "@" + password + "#EMR_MODE:0*", remoteAddress)); - } - - return position; - } - - private Position decodeB1(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_B_1, 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); - } - - 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; - } - - private Position decodeB(Channel channel, SocketAddress remoteAddress, String sentence) { - if (sentence.contains("EMR") || sentence.contains("SEM")) { - return decodeB2(channel, remoteAddress, sentence); - } else { - return decodeB1(channel, remoteAddress, sentence); - } - } - - @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 deleted file mode 100644 index f7826430f..000000000 --- a/src/org/traccar/protocol/Ardi01Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Ardi01Protocol extends BaseProtocol { - - public Ardi01Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Ardi01ProtocolDecoder(Ardi01Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/org/traccar/protocol/Ardi01ProtocolDecoder.java deleted file mode 100644 index 85e9ecfde..000000000 --- a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 Ardi01ProtocolDecoder extends BaseProtocolDecoder { - - public Ardi01ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // imei - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // longitude - .number("(-?d+.d+),") // latitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(-?d+.?d*),") // altitude - .number("(d+),") // satellites - .number("(d+),") // event - .number("(d+),") // battery - .number("(-?d+)") // temperature - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - int satellites = parser.nextInt(0); - position.setValid(satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - - position.set(Position.KEY_EVENT, parser.next()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ArknavProtocol.java b/src/org/traccar/protocol/ArknavProtocol.java deleted file mode 100644 index 3b485e4a5..000000000 --- a/src/org/traccar/protocol/ArknavProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class ArknavProtocol extends BaseProtocol { - - public ArknavProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ArknavProtocolDecoder.java b/src/org/traccar/protocol/ArknavProtocolDecoder.java deleted file mode 100644 index 4982e02fc..000000000 --- a/src/org/traccar/protocol/ArknavProtocolDecoder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class ArknavProtocolDecoder extends BaseProtocolDecoder { - - public ArknavProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // imei - .expression(".{6},") // id code - .number("ddd,") // status - .number("Lddd,") // version - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+.?d*),") // hdop - .number("(dd):(dd):(dd) ") // time (hh:mm:ss) - .number("(dd)-(dd)-(dd),") // date (dd-mm-yy) - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ArknavX8Protocol.java b/src/org/traccar/protocol/ArknavX8Protocol.java deleted file mode 100644 index a29bc1ad3..000000000 --- a/src/org/traccar/protocol/ArknavX8Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class ArknavX8Protocol extends BaseProtocol { - - public ArknavX8Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new ArknavX8ProtocolDecoder(ArknavX8Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java deleted file mode 100644 index b570f5423..000000000 --- a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class ArknavX8ProtocolDecoder extends BaseProtocolDecoder { - - public ArknavX8ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_1G = new PatternBuilder() - .expression("(..),") // type - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+)([NS]),") // latitude - .number("(d+)(dd.d+)([EW]),") // longitude - .number("(d+.d+),") // speed - .number("(d+),") // course - .number("(d+.d+),") // hdop - .number("(d+)") // status - .compile(); - - private static final Pattern PATTERN_2G = new PatternBuilder() - .expression("..,") // type - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+),") // satellites - .number("(d+.d+),") // altitude - .number("(d+.d+),") // power - .number("(d+.d+),") // battery - .number("(d+.d+)") // odometer - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.charAt(2) != ',') { - getDeviceSession(channel, remoteAddress, sentence.substring(0, 15)); - return null; - } - - switch (sentence.substring(0, 2)) { - case "1G": - case "1R": - case "1M": - return decode1G(channel, remoteAddress, sentence); - case "2G": - return decode2G(channel, remoteAddress, sentence); - default: - return null; - } - } - - private Position decode1G(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_1G, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_TYPE, parser.next()); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - position.set(Position.KEY_STATUS, parser.next()); - - return position; - } - - private Position decode2G(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_2G, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, parser.nextDateTime()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setAltitude(parser.nextDouble()); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1852 / 3600); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ArnaviProtocol.java b/src/org/traccar/protocol/ArnaviProtocol.java deleted file mode 100644 index afe491865..000000000 --- a/src/org/traccar/protocol/ArnaviProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class ArnaviProtocol extends BaseProtocol { - - public ArnaviProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new ArnaviProtocolDecoder(ArnaviProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/org/traccar/protocol/ArnaviProtocolDecoder.java deleted file mode 100644 index 7996cf429..000000000 --- a/src/org/traccar/protocol/ArnaviProtocolDecoder.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.Protocol; -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.util.regex.Pattern; - -public class ArnaviProtocolDecoder extends BaseProtocolDecoder { - - public ArnaviProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$AV,") - .number("Vd,") // type - .number("(d+),") // device id - .number("(d+),") // index - .number("(d+),") // power - .number("(d+),") // battery - .number("-?d+,") - .expression("[01],") // movement - .expression("([01]),") // ignition - .number("(d+),") // input - .number("d+,d+,") // input 1 - .number("d+,d+,").optional() // input 2 - .expression("[01],") // fix type - .number("(d+),") // satellites - .groupBegin() - .number("(d+.d+)?,") // altitude - .number("(?:d+.d+)?,") // geoid height - .groupEnd("?") - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd.d+)([NS]),") // latitude - .number("(ddd)(dd.d+)([EW]),") // longitude - .number("(d+.d+),") // speed - .number("(d+.d+),") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, parser.nextInt()); - position.set(Position.KEY_POWER, parser.nextInt() * 0.01); - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - position.set(Position.KEY_INPUT, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setAltitude(parser.nextDouble(0)); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/AstraProtocol.java b/src/org/traccar/protocol/AstraProtocol.java deleted file mode 100644 index 12b0dfb68..000000000 --- a/src/org/traccar/protocol/AstraProtocol.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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; - -public class AstraProtocol extends BaseProtocol { - - public AstraProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); - pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java deleted file mode 100644 index e6f546b9f..000000000 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; - -public class AstraProtocolDecoder extends BaseProtocolDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(AstraProtocolDecoder.class); - - public AstraProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_HEARTBEAT = 0x1A; - public static final int MSG_DATA = 0x10; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(new byte[] {0x06}), remoteAddress)); - } - - buf.readUnsignedByte(); // protocol - buf.readUnsignedShort(); // length - - String imei = String.format("%08d", buf.readUnsignedInt()) + String.format("%07d", buf.readUnsignedMedium()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() > 2) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // index - - position.setValid(true); - position.setLatitude(buf.readInt() * 0.000001); - position.setLongitude(buf.readInt() * 0.000001); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(1980, 1, 6).addMillis(buf.readUnsignedInt() * 1000L); - position.setTime(dateBuilder.getDate()); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte() * 2)); - position.setCourse(buf.readUnsignedByte() * 2); - - int reason = buf.readUnsignedMedium(); - position.set(Position.KEY_EVENT, reason); - - int status = buf.readUnsignedShort(); - position.set(Position.KEY_STATUS, status); - - position.set(Position.PREFIX_IO + 1, buf.readUnsignedByte()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedByte()); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // max journey speed - buf.skipBytes(6); // accelerometer - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort()); - buf.readUnsignedShort(); // journey idle time - - position.setAltitude(buf.readUnsignedByte() * 20); - - int quality = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, quality & 0xf); - position.set(Position.KEY_RSSI, quality >> 4); - - buf.readUnsignedByte(); // geofence events - - if (BitUtil.check(status, 8)) { - 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, UnitsConverter.msFromHours(buf.readUnsignedShort())); - } - - if (BitUtil.check(status, 6)) { - LOGGER.warn("Extension data is not supported"); - return position; - } - - positions.add(position); - - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/At2000FrameDecoder.java b/src/org/traccar/protocol/At2000FrameDecoder.java deleted file mode 100644 index 5fa82a5f7..000000000 --- a/src/org/traccar/protocol/At2000FrameDecoder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; -import org.traccar.NetworkMessage; - -public class At2000FrameDecoder extends BaseFrameDecoder { - - private static final int BLOCK_LENGTH = 16; - private static final int ACK_LENGTH = 496; - - private boolean firstPacket = true; - - private ByteBuf currentBuffer; - private int acknowledgedBytes; - - private void sendResponse(Channel channel) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(2 * BLOCK_LENGTH); - response.writeByte(At2000ProtocolDecoder.MSG_ACKNOWLEDGEMENT); - response.writeMedium(1); - response.writeByte(0x00); // success - response.writerIndex(2 * BLOCK_LENGTH); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 5) { - return null; - } - - int length; - if (firstPacket) { - firstPacket = false; - length = buf.getUnsignedMediumLE(buf.readerIndex() + 2); - } else { - length = buf.getUnsignedMediumLE(buf.readerIndex() + 1); - } - - length += BLOCK_LENGTH; - if (length % BLOCK_LENGTH != 0) { - length = (length / BLOCK_LENGTH + 1) * BLOCK_LENGTH; - } - - if ((buf.readableBytes() >= length || buf.readableBytes() % ACK_LENGTH == 0) - && (buf != currentBuffer || buf.readableBytes() > acknowledgedBytes)) { - sendResponse(channel); - currentBuffer = buf; - acknowledgedBytes = buf.readableBytes(); - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/At2000Protocol.java b/src/org/traccar/protocol/At2000Protocol.java deleted file mode 100644 index 5894f3eab..000000000 --- a/src/org/traccar/protocol/At2000Protocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class At2000Protocol extends BaseProtocol { - - public At2000Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new At2000FrameDecoder()); - pipeline.addLast(new At2000ProtocolDecoder(At2000Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java deleted file mode 100644 index 43798eb67..000000000 --- a/src/org/traccar/protocol/At2000ProtocolDecoder.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DataConverter; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class At2000ProtocolDecoder extends BaseProtocolDecoder { - - private static final int BLOCK_LENGTH = 16; - - public At2000ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_ACKNOWLEDGEMENT = 0x00; - public static final int MSG_DEVICE_ID = 0x01; - public static final int MSG_TRACK_REQUEST = 0x88; - public static final int MSG_TRACK_RESPONSE = 0x89; - public static final int MSG_SESSION_END = 0x0c; - - private Cipher cipher; - - private static void sendRequest(Channel channel) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(BLOCK_LENGTH); - response.writeByte(MSG_TRACK_REQUEST); - response.writeMedium(0); - response.writerIndex(BLOCK_LENGTH); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (buf.getUnsignedByte(buf.readerIndex()) == 0x01) { - buf.readUnsignedByte(); // codec id - } - - int type = buf.readUnsignedByte(); - buf.readUnsignedMediumLE(); // length - buf.skipBytes(BLOCK_LENGTH - 1 - 3); - - if (type == MSG_DEVICE_ID) { - - String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); - if (getDeviceSession(channel, remoteAddress, imei) != null) { - - byte[] iv = new byte[BLOCK_LENGTH]; - buf.readBytes(iv); - IvParameterSpec ivSpec = new IvParameterSpec(iv); - - SecretKeySpec keySpec = new SecretKeySpec( - DataConverter.parseHex("000102030405060708090a0b0c0d0e0f"), "AES"); - - cipher = Cipher.getInstance("AES/CBC/NoPadding"); - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); - - byte[] data = new byte[BLOCK_LENGTH]; - buf.readBytes(data); - cipher.update(data); - - } - - } else if (type == MSG_TRACK_RESPONSE) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (buf.capacity() <= BLOCK_LENGTH) { - return null; // empty message - } - - List<Position> positions = new LinkedList<>(); - - 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()); - - buf.readUnsignedShortLE(); // index - buf.readUnsignedShortLE(); // reserved - - position.setValid(true); - - position.setTime(new Date(buf.readLongLE() * 1000)); - - position.setLatitude(buf.readFloatLE()); - position.setLongitude(buf.readFloatLE()); - position.setAltitude(buf.readFloatLE()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); - position.setCourse(buf.readFloatLE()); - - 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.readUnsignedShortLE()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - - 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()); - - positions.add(position); - - } - } finally { - buf.release(); - } - - return positions; - - } - - if (type == MSG_DEVICE_ID) { - sendRequest(channel); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AtrackFrameDecoder.java b/src/org/traccar/protocol/AtrackFrameDecoder.java deleted file mode 100644 index f071e2d97..000000000 --- a/src/org/traccar/protocol/AtrackFrameDecoder.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * 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; -import org.traccar.helper.BufferUtil; - -import java.nio.charset.StandardCharsets; - -public class AtrackFrameDecoder extends BaseFrameDecoder { - - private static final int KEEPALIVE_LENGTH = 12; - - @Override - protected Object decode( - 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.readRetainedSlice(KEEPALIVE_LENGTH); - } - - } 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.readRetainedSlice(length); - } - } - - } else { - - int lengthStart = buf.indexOf(buf.readerIndex() + 3, buf.writerIndex(), (byte) ',') + 1; - if (lengthStart > 0) { - int lengthEnd = buf.indexOf(lengthStart, buf.writerIndex(), (byte) ','); - if (lengthEnd > 0) { - int length = lengthEnd + Integer.parseInt(buf.toString( - lengthStart, lengthEnd - lengthStart, StandardCharsets.US_ASCII)); - if (buf.readableBytes() > length && buf.getByte(buf.readerIndex() + length) == '\n') { - length += 1; - } - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - } - } else { - int endIndex = BufferUtil.indexOf("\r\n", buf); - if (endIndex > 0) { - return buf.readRetainedSlice(endIndex - buf.readerIndex() + 2); - } - } - - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AtrackProtocol.java b/src/org/traccar/protocol/AtrackProtocol.java deleted file mode 100644 index 8e5cfe9ff..000000000 --- a/src/org/traccar/protocol/AtrackProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class AtrackProtocol extends BaseProtocol { - - public AtrackProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AtrackFrameDecoder()); - pipeline.addLast(new AtrackProtocolEncoder()); - pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AtrackProtocolEncoder()); - pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java deleted file mode 100644 index 71bb6791c..000000000 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ /dev/null @@ -1,586 +0,0 @@ -/* - * 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. - * 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.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -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.nio.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class AtrackProtocolDecoder extends BaseProtocolDecoder { - - private static final int MIN_DATA_LENGTH = 40; - - private boolean longDate; - private boolean decimalFuel; - private boolean custom; - private String form; - - private final Map<Integer, String> alarmMap = new HashMap<>(); - - public AtrackProtocolDecoder(Protocol protocol) { - super(protocol); - - longDate = Context.getConfig().getBoolean(getProtocolName() + ".longDate"); - decimalFuel = Context.getConfig().getBoolean(getProtocolName() + ".decimalFuel"); - - custom = Context.getConfig().getBoolean(getProtocolName() + ".custom"); - form = Context.getConfig().getString(getProtocolName() + ".form"); - if (form != null) { - custom = true; - } - - for (String pair : Context.getConfig().getString(getProtocolName() + ".alarmMap", "").split(",")) { - if (!pair.isEmpty()) { - alarmMap.put( - Integer.parseInt(pair.substring(0, pair.indexOf('='))), pair.substring(pair.indexOf('=') + 1)); - } - } - } - - public void setLongDate(boolean longDate) { - this.longDate = longDate; - } - - public void setCustom(boolean custom) { - this.custom = custom; - } - - private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(12); - response.writeShort(0xfe02); - response.writeLong(rawId); - response.writeShort(index); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - 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.readSlice(index - buf.readerIndex()).toString(StandardCharsets.US_ASCII); - } - buf.readByte(); - return result; - } - - private void readTextCustomData(Position position, String data, String form) { - CellTower cellTower = new CellTower(); - String[] keys = form.substring(1).split("%"); - String[] values = data.split(",|\r\n"); - for (int i = 0; i < Math.min(keys.length, values.length); i++) { - switch (keys[i]) { - case "SA": - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - case "MV": - position.set(Position.KEY_POWER, Integer.parseInt(values[i]) * 0.1); - break; - case "BV": - position.set(Position.KEY_BATTERY, Integer.parseInt(values[i]) * 0.1); - break; - case "GQ": - cellTower.setSignalStrength(Integer.parseInt(values[i])); - break; - case "CE": - cellTower.setCellId(Long.parseLong(values[i])); - break; - case "LC": - cellTower.setLocationAreaCode(Integer.parseInt(values[i])); - break; - case "CN": - if (values[i].length() > 3) { - cellTower.setMobileCountryCode(Integer.parseInt(values[i].substring(0, 3))); - cellTower.setMobileNetworkCode(Integer.parseInt(values[i].substring(3))); - } - break; - case "PC": - position.set(Position.PREFIX_COUNT + 1, Integer.parseInt(values[i])); - break; - case "AT": - position.setAltitude(Integer.parseInt(values[i])); - break; - case "RP": - position.set(Position.KEY_RPM, Integer.parseInt(values[i])); - break; - case "GS": - position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); - break; - case "DT": - position.set(Position.KEY_ARCHIVE, Integer.parseInt(values[i]) == 1); - break; - case "VN": - position.set(Position.KEY_VIN, values[i]); - break; - case "TR": - position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i])); - break; - case "ET": - position.set(Position.PREFIX_TEMP + 1, Integer.parseInt(values[i])); - break; - case "FL": - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i])); - break; - case "FC": - position.set(Position.KEY_FUEL_CONSUMPTION, Integer.parseInt(values[i])); - break; - case "AV1": - position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i])); - break; - default: - break; - } - } - - if (cellTower.getMobileCountryCode() != null - && cellTower.getMobileNetworkCode() != null - && cellTower.getCellId() != null - && cellTower.getLocationAreaCode() != null) { - position.setNetwork(new Network(cellTower)); - } else if (cellTower.getSignalStrength() != null) { - position.set(Position.KEY_RSSI, cellTower.getSignalStrength()); - } - } - - private void readBinaryCustomData(Position position, ByteBuf buf, String form) { - CellTower cellTower = new CellTower(); - String[] keys = form.substring(1).split("%"); - for (String key : keys) { - switch (key) { - case "SA": - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case "MV": - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); - break; - case "BV": - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); - break; - case "GQ": - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - break; - case "CE": - cellTower.setCellId(buf.readUnsignedInt()); - break; - case "LC": - cellTower.setLocationAreaCode(buf.readUnsignedShort()); - break; - case "CN": - int combinedMobileCodes = (int) (buf.readUnsignedInt() % 100000); // cccnn - cellTower.setMobileCountryCode(combinedMobileCodes / 100); - cellTower.setMobileNetworkCode(combinedMobileCodes % 100); - break; - case "RL": - buf.readUnsignedByte(); // rxlev - break; - case "PC": - position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedInt()); - break; - case "AT": - position.setAltitude(buf.readUnsignedInt()); - break; - case "RP": - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case "GS": - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case "DT": - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() == 1); - break; - case "VN": - position.set(Position.KEY_VIN, readString(buf)); - break; - case "MF": - buf.readUnsignedShort(); // mass air flow rate - break; - case "EL": - buf.readUnsignedByte(); // engine load - break; - case "TR": - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - case "ET": - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); - break; - case "FL": - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case "ML": - buf.readUnsignedByte(); // mil status - break; - case "FC": - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); - break; - case "CI": - readString(buf); // format string - break; - case "AV1": - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - break; - case "NC": - readString(buf); // gsm neighbor cell info - break; - case "SM": - buf.readUnsignedShort(); // max speed between reports - break; - case "GL": - readString(buf); // google link - break; - case "MA": - readString(buf); // mac address - break; - case "PD": - buf.readUnsignedByte(); // pending code status - break; - case "CD": - readString(buf); // sim cid - break; - case "CM": - buf.readLong(); // imsi - break; - case "GN": - buf.skipBytes(60); // g sensor data - break; - case "GV": - buf.skipBytes(6); // maximum g force - break; - case "ME": - buf.readLong(); // imei - break; - case "IA": - buf.readUnsignedByte(); // intake air temperature - break; - case "MP": - buf.readUnsignedByte(); // manifold absolute pressure - break; - default: - break; - } - } - - if (cellTower.getMobileCountryCode() != null - && cellTower.getMobileNetworkCode() != null - && cellTower.getCellId() != null && cellTower.getCellId() != 0 - && cellTower.getLocationAreaCode() != null) { - position.setNetwork(new Network(cellTower)); - } else if (cellTower.getSignalStrength() != null) { - position.set(Position.KEY_RSSI, cellTower.getSignalStrength()); - } - } - - private static final Pattern PATTERN_INFO = new PatternBuilder() - .text("$INFO=") - .number("(d+),") // unit id - .expression("([^,]+),") // model - .expression("([^,]+),") // firmware version - .number("d+,") // imei - .number("d+,") // imsi - .number("d+,") // sim card id - .number("(d+),") // power - .number("(d+),") // battery - .number("(d+),") // satellites - .number("d+,") // gsm status - .number("(d+),") // rssi - .number("d+,") // connection status - .number("d+") // antenna status - .any() - .compile(); - - private Position decodeInfo(Channel channel, SocketAddress remoteAddress, String sentence) { - - Position position = new Position(getProtocolName()); - - getLastLocation(position, null); - - DeviceSession deviceSession; - - if (sentence.startsWith("$INFO")) { - - Parser parser = new Parser(PATTERN_INFO, sentence); - if (!parser.matches()) { - return null; - } - - deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - - position.set("model", parser.next()); - position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_POWER, parser.nextInt() * 0.1); - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextInt()); - - } else { - - deviceSession = getDeviceSession(channel, remoteAddress); - - position.set(Position.KEY_RESULT, sentence); - - } - - if (deviceSession == null) { - return null; - } else { - position.setDeviceId(deviceSession.getDeviceId()); - return position; - } - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // date and time - .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 - .expression("[^,]*,") // text message - .expression("(.*)") // custom data - .optional(2) - .compile(); - - private List<Position> decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - - int startIndex = 0; - for (int i = 0; i < 4; i++) { - startIndex = sentence.indexOf(',', startIndex + 1); - } - int endIndex = sentence.indexOf(',', startIndex + 1); - - String imei = sentence.substring(startIndex + 1, endIndex); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - String[] lines = sentence.substring(endIndex + 1).split("\r\n"); - - for (String line : lines) { - Position position = decodeTextLine(deviceSession, line); - if (position != null) { - positions.add(position); - } - } - - return positions; - } - - - private Position decodeTextLine(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - - String time = parser.next(); - if (time.length() >= 14) { - try { - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(time)); - } catch (ParseException e) { - throw new RuntimeException(e); - } - } else { - position.setTime(new Date(Long.parseLong(time) * 1000)); - } - - 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()); - - if (parser.hasNext()) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - } - - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 2, parser.nextInt()); - - if (custom) { - String data = parser.next(); - String form = this.form; - if (form == null) { - form = data.substring(0, data.indexOf(',')).substring("%CI".length()); - data = data.substring(data.indexOf(',') + 1); - } - readTextCustomData(position, data, form); - } - - return position; - } - - private List<Position> decodeBinary(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - buf.skipBytes(2); // prefix - buf.readUnsignedShort(); // checksum - buf.readUnsignedShort(); // length - int index = buf.readUnsignedShort(); - - long id = buf.readLong(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); - if (deviceSession == null) { - return null; - } - - sendResponse(channel, remoteAddress, id, index); - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() >= MIN_DATA_LENGTH) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (longDate) { - - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - buf.skipBytes(7 + 7); - - } else { - position.setFixTime(new Date(buf.readUnsignedInt() * 1000)); - position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000)); - buf.readUnsignedInt(); // send time - } - - position.setValid(true); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); - position.setCourse(buf.readUnsignedShort()); - - int type = buf.readUnsignedByte(); - position.set(Position.KEY_TYPE, type); - position.set(Position.KEY_ALARM, alarmMap.get(type)); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); - position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1); - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.001); - - position.set(Position.KEY_DRIVER_UNIQUE_ID, readString(buf)); - - position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1); - position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1); - - String message = readString(buf); - if (message != null && !message.isEmpty()) { - Pattern pattern = Pattern.compile("FULS:F=(\\p{XDigit}+) t=(\\p{XDigit}+) N=(\\p{XDigit}+)"); - Matcher matcher = pattern.matcher(message); - if (matcher.find()) { - int value = Integer.parseInt(matcher.group(3), decimalFuel ? 10 : 16); - position.set(Position.KEY_FUEL_LEVEL, value * 0.1); - } else { - position.set("message", message); - } - } - - if (custom) { - String form = this.form; - if (form == null) { - form = readString(buf).trim().substring("%CI".length()); - } - readBinaryCustomData(position, buf, form); - } - - positions.add(position); - - } - - 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.retain(), 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 deleted file mode 100644 index 1e085cb26..000000000 --- a/src/org/traccar/protocol/AtrackProtocolEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class AtrackProtocolEncoder extends BaseProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return Unpooled.copiedBuffer( - command.getString(Command.KEY_DATA) + "\r\n", StandardCharsets.US_ASCII); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/AuroProtocol.java b/src/org/traccar/protocol/AuroProtocol.java deleted file mode 100644 index b8ebdaa75..000000000 --- a/src/org/traccar/protocol/AuroProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class AuroProtocol extends BaseProtocol { - - public AuroProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AuroProtocolDecoder(AuroProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AuroProtocolDecoder.java b/src/org/traccar/protocol/AuroProtocolDecoder.java deleted file mode 100644 index d7916147b..000000000 --- a/src/org/traccar/protocol/AuroProtocolDecoder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 AuroProtocolDecoder extends BaseProtocolDecoder { - - public AuroProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("M(dddd)") // index - .number("Td+") // phone - .number("I(d+)") // imei - .number("Ed+W") - .text("*****") - .number("d{8}d{4}") // local time - .expression(".{8}#.{8}") - .number("d{10}") // status - .number("([-+])(ddd)(dd)(dddd)") // longitude - .number("([-+])(ddd)(dd)(dddd)") // latitude - .number("(dd)(dd)(dddd)") // date (ddmmyyyy) - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(ddd)") // course - .number("d{6}") - .number("(ddd)") // speed - .number("d") - .number("(dd)") // battery - .expression("([01])") // charging - .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; - } - - Position position = new Position(getProtocolName()); - - position.set(Position.KEY_INDEX, parser.nextInt(0)); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN)); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setCourse(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); - - return position; - } - -} diff --git a/src/org/traccar/protocol/AustinNbProtocol.java b/src/org/traccar/protocol/AustinNbProtocol.java deleted file mode 100644 index 32bfc0aae..000000000 --- a/src/org/traccar/protocol/AustinNbProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class AustinNbProtocol extends BaseProtocol { - - public AustinNbProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new AustinNbProtocolDecoder(AustinNbProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/org/traccar/protocol/AustinNbProtocolDecoder.java deleted file mode 100644 index dc6f3d280..000000000 --- a/src/org/traccar/protocol/AustinNbProtocolDecoder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.Parser; -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 AustinNbProtocolDecoder extends BaseProtocolDecoder { - - public AustinNbProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+);") // imei - .number("(dddd)-(dd)-(dd) ") // date - .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(); - - @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.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS, TimeZone.getDefault().getID())); - - position.setValid(true); - 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 deleted file mode 100644 index 69f28133f..000000000 --- a/src/org/traccar/protocol/AutoFonFrameDecoder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2015 Vitaly Litvak (vitavaque@gmail.com) - * - * 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 AutoFonFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - // Check minimum length - if (buf.readableBytes() < 12) { - return null; - } - - int length; - switch (buf.getUnsignedByte(buf.readerIndex())) { - case AutoFonProtocolDecoder.MSG_LOGIN: - length = 12; - break; - case AutoFonProtocolDecoder.MSG_LOCATION: - length = 78; - break; - case AutoFonProtocolDecoder.MSG_HISTORY: - length = 257; - break; - case AutoFonProtocolDecoder.MSG_45_LOGIN: - length = 19; - break; - case AutoFonProtocolDecoder.MSG_45_LOCATION: - length = 34; - break; - default: - length = 0; - break; - } - - // Check length and return buffer - if (length != 0 && buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AutoFonProtocol.java b/src/org/traccar/protocol/AutoFonProtocol.java deleted file mode 100644 index 08b5edc7d..000000000 --- a/src/org/traccar/protocol/AutoFonProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class AutoFonProtocol extends BaseProtocol { - - public AutoFonProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AutoFonFrameDecoder()); - pipeline.addLast(new AutoFonProtocolDecoder(AutoFonProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/org/traccar/protocol/AutoFonProtocolDecoder.java deleted file mode 100644 index aa05ca2d7..000000000 --- a/src/org/traccar/protocol/AutoFonProtocolDecoder.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2015 Vitaly Litvak (vitavaque@gmail.com) - * - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -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.LinkedList; -import java.util.List; - -public class AutoFonProtocolDecoder extends BaseProtocolDecoder { - - public AutoFonProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN = 0x10; - public static final int MSG_LOCATION = 0x11; - public static final int MSG_HISTORY = 0x12; - - public static final int MSG_45_LOGIN = 0x41; - public static final int MSG_45_LOCATION = 0x02; - - private static double convertCoordinate(int raw) { - int degrees = raw / 1000000; - double minutes = (raw % 1000000) / 10000.0; - return degrees + minutes / 60; - } - - private static double convertCoordinate(short degrees, int minutes) { - double value = degrees + BitUtil.from(minutes, 4) / 600000.0; - if (BitUtil.check(minutes, 0)) { - return value; - } else { - return -value; - } - } - - private Position decodePosition(DeviceSession deviceSession, ByteBuf buf, boolean history) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (!history) { - buf.readUnsignedByte(); // interval - buf.skipBytes(8); // settings - } - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - if (!history) { - buf.readUnsignedShort(); - } - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - buf.skipBytes(6); // time - - if (!history) { - for (int i = 0; i < 2; i++) { - buf.skipBytes(5); // time - buf.readUnsignedShort(); // interval - buf.skipBytes(5); // mode - } - } - - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - - int rssi = buf.readUnsignedByte(); - CellTower cellTower = CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort(), rssi); - position.setNetwork(new Network(cellTower)); - - int valid = buf.readUnsignedByte(); - position.setValid((valid & 0xc0) != 0); - position.set(Position.KEY_SATELLITES, valid & 0x3f); - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - position.setLatitude(convertCoordinate(buf.readInt())); - position.setLongitude(convertCoordinate(buf.readInt())); - position.setAltitude(buf.readShort()); - position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedByte() * 2.0); - - position.set(Position.KEY_HDOP, buf.readUnsignedShort()); - - buf.readUnsignedShort(); // reserved - buf.readUnsignedByte(); // checksum - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int type = buf.readUnsignedByte(); - - if (type == MSG_LOGIN || type == MSG_45_LOGIN) { - - if (type == MSG_LOGIN) { - buf.readUnsignedByte(); // hardware version - buf.readUnsignedByte(); // software version - } - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - - if (deviceSession != null && channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeBytes("resp_crc=".getBytes(StandardCharsets.US_ASCII)); - response.writeByte(buf.getByte(buf.writerIndex() - 1)); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - return null; - - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (type == MSG_LOCATION) { - - return decodePosition(deviceSession, buf, false); - - } else if (type == MSG_HISTORY) { - - int count = buf.readUnsignedByte() & 0x0f; - buf.readUnsignedShort(); // total count - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < count; i++) { - positions.add(decodePosition(deviceSession, buf, true)); - } - - return positions; - - } else if (type == MSG_45_LOCATION) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - short status = buf.readUnsignedByte(); - if (BitUtil.check(status, 7)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - position.set(Position.KEY_BATTERY, BitUtil.to(status, 7)); - - buf.skipBytes(2); // remaining time - - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - - buf.skipBytes(2); // timer (interval and units) - buf.readByte(); // mode - buf.readByte(); // gprs sending interval - - buf.skipBytes(6); // mcc, mnc, lac, cid - - int valid = buf.readUnsignedByte(); - position.setValid(BitUtil.from(valid, 6) != 0); - position.set(Position.KEY_SATELLITES, BitUtil.from(valid, 6)); - - int time = buf.readUnsignedMedium(); - int date = buf.readUnsignedMedium(); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(time / 10000, time / 100 % 100, time % 100) - .setDateReverse(date / 10000, date / 100 % 100, date % 100); - position.setTime(dateBuilder.getDate()); - - position.setLatitude(convertCoordinate(buf.readUnsignedByte(), buf.readUnsignedMedium())); - position.setLongitude(convertCoordinate(buf.readUnsignedByte(), buf.readUnsignedMedium())); - position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedShort()); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/AutoGradeProtocol.java b/src/org/traccar/protocol/AutoGradeProtocol.java deleted file mode 100644 index c6dbb681e..000000000 --- a/src/org/traccar/protocol/AutoGradeProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class AutoGradeProtocol extends BaseProtocol { - - public AutoGradeProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AutoGradeProtocolDecoder(AutoGradeProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java deleted file mode 100644 index 5052450b5..000000000 --- a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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.util.regex.Pattern; - -public class AutoGradeProtocolDecoder extends BaseProtocolDecoder { - - public AutoGradeProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .number("d{12}") // index - .number("(d{15})") // imei - .number("(dd)(dd)(dd)") // date (ddmmyy) - .expression("([AV])") // validity - .number("(d+)(dd.d+)([NS])") // latitude - .number("(d+)(dd.d+)([EW])") // longitude - .number("([d.]{5})") // speed - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("([d.]{6})") // course - .expression("(.)") // status - .number("A(xxxx)") - .number("B(xxxx)") - .number("C(xxxx)") - .number("D(xxxx)") - .number("E(xxxx)") - .number("K(xxxx)") - .number("L(xxxx)") - .number("M(xxxx)") - .number("N(xxxx)") - .number("O(xxxx)") - .any() - .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()); - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.setCourse(parser.nextDouble(0)); - - int status = parser.next().charAt(0); - position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); - - for (int i = 1; i <= 5; i++) { - position.set(Position.PREFIX_ADC + i, parser.next()); - } - - for (int i = 1; i <= 5; i++) { - position.set("can" + i, parser.next()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/AutoTrackProtocol.java b/src/org/traccar/protocol/AutoTrackProtocol.java deleted file mode 100644 index 6aa7558bf..000000000 --- a/src/org/traccar/protocol/AutoTrackProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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; -public class AutoTrackProtocol extends BaseProtocol { - - public AutoTrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); - pipeline.addLast(new AutoTrackProtocolDecoder(AutoTrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/org/traccar/protocol/AutoTrackProtocolDecoder.java deleted file mode 100644 index 3c1fd256b..000000000 --- a/src/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.Checksum; -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(Protocol 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; - public static final int MSG_TELEMETRY_CONFIRM = 123; - - private Position decodeTelemetry( - Channel channel, SocketAddress remoteAddress, DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(1009843200000L + 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())); - buf.readUnsignedShortLE(); // max speed - - 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()); - - int index = buf.readUnsignedShortLE(); - - buf.readUnsignedShortLE(); // checksum - - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeInt(0xF1F1F1F1); // sync - response.writeByte(MSG_TELEMETRY_CONFIRM); - response.writeShortLE(2); // length - response.writeShortLE(index); - response.writeShort(Checksum.crc16(Checksum.CRC16_XMODEM, response.nioBuffer())); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - 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); - response.writeShort(Checksum.crc16(Checksum.CRC16_XMODEM, response.nioBuffer())); - 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(channel, remoteAddress, deviceSession, buf); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/AvemaProtocol.java b/src/org/traccar/protocol/AvemaProtocol.java deleted file mode 100644 index dbfab4dea..000000000 --- a/src/org/traccar/protocol/AvemaProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class AvemaProtocol extends BaseProtocol { - - public AvemaProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new AvemaProtocolDecoder(AvemaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/AvemaProtocolDecoder.java b/src/org/traccar/protocol/AvemaProtocolDecoder.java deleted file mode 100644 index 16a31162a..000000000 --- a/src/org/traccar/protocol/AvemaProtocolDecoder.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index 71fc7cb26..000000000 --- a/src/org/traccar/protocol/Avl301Protocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class Avl301Protocol extends BaseProtocol { - - public Avl301Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); - pipeline.addLast(new Avl301ProtocolDecoder(Avl301Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/org/traccar/protocol/Avl301ProtocolDecoder.java deleted file mode 100644 index f6b7db2d6..000000000 --- a/src/org/traccar/protocol/Avl301ProtocolDecoder.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class Avl301ProtocolDecoder extends BaseProtocolDecoder { - - public Avl301ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private String readImei(ByteBuf buf) { - int b = buf.readUnsignedByte(); - StringBuilder imei = new StringBuilder(); - imei.append(b & 0x0F); - for (int i = 0; i < 7; i++) { - b = buf.readUnsignedByte(); - imei.append((b & 0xF0) >> 4); - imei.append(b & 0x0F); - } - return imei.toString(); - } - - public static final int MSG_LOGIN = 'L'; - public static final int MSG_STATUS = 'H'; - public static final int MSG_GPS_LBS_STATUS = '$'; - - private void sendResponse(Channel channel, int type) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(5); - response.writeByte('$'); - response.writeByte(type); - response.writeByte('#'); - response.writeByte('\r'); response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(1); // header - int type = buf.readUnsignedByte(); - buf.readUnsignedByte(); // length - - if (type == MSG_LOGIN) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readImei(buf)); - if (deviceSession == null) { - sendResponse(channel, type); - } - - } else if (type == MSG_STATUS) { - - sendResponse(channel, type); - - } else if (type == MSG_GPS_LBS_STATUS) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - int gpsLength = buf.readUnsignedByte(); // gps len and sat - position.set(Position.KEY_SATELLITES, gpsLength & 0xf); - - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); // satellites - - double latitude = buf.readUnsignedInt() / 600000.0; - double longitude = buf.readUnsignedInt() / 600000.0; - position.setSpeed(buf.readUnsignedByte()); - - int union = buf.readUnsignedShort(); // course and flags - position.setCourse(union & 0x03FF); - position.setValid((union & 0x1000) != 0); - if ((union & 0x0400) != 0) { - latitude = -latitude; - } - if ((union & 0x0800) != 0) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - - if ((union & 0x4000) != 0) { - position.set("acc", (union & 0x8000) != 0); - } - - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedMedium()))); - - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - int flags = buf.readUnsignedByte(); - position.set("acc", (flags & 0x2) != 0); - - // parse other flags - - position.set(Position.KEY_POWER, buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/BceFrameDecoder.java b/src/org/traccar/protocol/BceFrameDecoder.java deleted file mode 100644 index 381a97696..000000000 --- a/src/org/traccar/protocol/BceFrameDecoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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 BceFrameDecoder extends BaseFrameDecoder { - - private static final int HANDSHAKE_LENGTH = 7; // "#BCE#\r\n" - - private boolean header = true; - - private static byte checksum(ByteBuf buf, int end) { - byte result = 0; - for (int i = 0; i < end; i++) { - result += buf.getByte(buf.readerIndex() + i); - } - return result; - } - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (header && buf.readableBytes() >= HANDSHAKE_LENGTH) { - buf.skipBytes(HANDSHAKE_LENGTH); - header = false; - } - - int end = 8; // IMEI - - while (buf.readableBytes() >= end + 2 + 1 + 1 + 1) { - end += buf.getUnsignedShortLE(buf.readerIndex() + end) + 2; - - if (buf.readableBytes() > end && checksum(buf, end) == buf.getByte(buf.readerIndex() + end)) { - return buf.readRetainedSlice(end + 1); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/BceProtocol.java b/src/org/traccar/protocol/BceProtocol.java deleted file mode 100644 index 6453a05a9..000000000 --- a/src/org/traccar/protocol/BceProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class BceProtocol extends BaseProtocol { - - public BceProtocol() { - setSupportedDataCommands( - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new BceFrameDecoder()); - pipeline.addLast(new BceProtocolEncoder()); - pipeline.addLast(new BceProtocolDecoder(BceProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/BceProtocolDecoder.java b/src/org/traccar/protocol/BceProtocolDecoder.java deleted file mode 100644 index ed810bebb..000000000 --- a/src/org/traccar/protocol/BceProtocolDecoder.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class BceProtocolDecoder extends BaseProtocolDecoder { - - public BceProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final int DATA_TYPE = 7; - - public static final int MSG_ASYNC_STACK = 0xA5; - public static final int MSG_STACK_COFIRM = 0x19; - public static final int MSG_TIME_TRIGGERED = 0xA0; - public static final int MSG_OUTPUT_CONTROL = 0x41; - public static final int MSG_OUTPUT_CONTROL_ACK = 0xC1; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - String imei = String.format("%015d", buf.readLongLE()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() > 1) { - - int dataEnd = buf.readUnsignedShortLE() + buf.readerIndex(); - int type = buf.readUnsignedByte(); - - if (type != MSG_ASYNC_STACK && type != MSG_TIME_TRIGGERED) { - return null; - } - - int confirmKey = buf.readUnsignedByte() & 0x7F; - - while (buf.readerIndex() < dataEnd) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int structEnd = buf.readUnsignedByte() + buf.readerIndex(); - - long time = buf.readUnsignedIntLE(); - if ((time & 0x0f) == DATA_TYPE) { - - time = time >> 4 << 1; - time += 0x47798280; // 01/01/2008 - position.setTime(new Date(time * 1000)); - - // Read masks - int mask; - List<Integer> masks = new LinkedList<>(); - do { - mask = buf.readUnsignedShortLE(); - masks.add(mask); - } while (BitUtil.check(mask, 15)); - - mask = masks.get(0); - - if (BitUtil.check(mask, 0)) { - position.setValid(true); - position.setLongitude(buf.readFloatLE()); - position.setLatitude(buf.readFloatLE()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - 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() * 2); - position.setAltitude(buf.readUnsignedShortLE()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - } - - if (BitUtil.check(mask, 1)) { - 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.readUnsignedShortLE()); - } - } - - if (BitUtil.check(mask, 10)) { - buf.skipBytes(4); - } - if (BitUtil.check(mask, 11)) { - buf.skipBytes(4); - } - if (BitUtil.check(mask, 12)) { - buf.skipBytes(2); - } - if (BitUtil.check(mask, 13)) { - buf.skipBytes(2); - } - - if (BitUtil.check(mask, 14)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShortLE(), buf.readUnsignedByte(), - buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), - buf.readUnsignedByte()))); - buf.readUnsignedByte(); - } - - if (BitUtil.check(mask, 0)) { - positions.add(position); - } - } - - buf.readerIndex(structEnd); - } - - // Send response - if (type == MSG_ASYNC_STACK && channel != null) { - ByteBuf response = Unpooled.buffer(8 + 2 + 2 + 1); - response.writeLongLE(Long.parseLong(imei)); - response.writeShortLE(2); - response.writeByte(MSG_STACK_COFIRM); - response.writeByte(confirmKey); - - int checksum = 0; - for (int i = 0; i < response.writerIndex(); i++) { - checksum += response.getUnsignedByte(i); - } - response.writeByte(checksum); - - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/BceProtocolEncoder.java b/src/org/traccar/protocol/BceProtocolEncoder.java deleted file mode 100644 index 1bbf3db12..000000000 --- a/src/org/traccar/protocol/BceProtocolEncoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -public class BceProtocolEncoder extends BaseProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - if (command.getType().equals(Command.TYPE_OUTPUT_CONTROL)) { - ByteBuf buf = Unpooled.buffer(); - - buf.writeLongLE(Long.parseLong(getUniqueId(command.getDeviceId()))); - buf.writeShortLE(1 + 1 + 3 + 1); // length - buf.writeByte(BceProtocolDecoder.MSG_OUTPUT_CONTROL); - buf.writeByte(command.getInteger(Command.KEY_INDEX) == 1 ? 0x0A : 0x0B); - buf.writeByte(0xFF); // index - buf.writeByte(0x00); // form id - buf.writeShortLE(Integer.parseInt(command.getString(Command.KEY_DATA)) > 0 ? 0x0055 : 0x0000); - buf.writeByte(Checksum.sum(buf.nioBuffer())); - - return buf; - } else { - return null; - } - } - -} diff --git a/src/org/traccar/protocol/BlackKiteProtocol.java b/src/org/traccar/protocol/BlackKiteProtocol.java deleted file mode 100644 index 617a24d7a..000000000 --- a/src/org/traccar/protocol/BlackKiteProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2015 Vijay Kumar (vijaykumar@zilogic.com) - * 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. - * 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; - -public class BlackKiteProtocol extends BaseProtocol { - - public BlackKiteProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new GalileoFrameDecoder()); - pipeline.addLast(new BlackKiteProtocolDecoder(BlackKiteProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/org/traccar/protocol/BlackKiteProtocolDecoder.java deleted file mode 100644 index dca4b908a..000000000 --- a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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"); - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public class BlackKiteProtocolDecoder extends BaseProtocolDecoder { - - public BlackKiteProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final int TAG_IMEI = 0x03; - private static final int TAG_DATE = 0x20; - private static final int TAG_COORDINATES = 0x30; - private static final int TAG_SPEED_COURSE = 0x33; - private static final int TAG_ALTITUDE = 0x34; - private static final int TAG_STATUS = 0x40; - private static final int TAG_DIGITAL_OUTPUTS = 0x45; - private static final int TAG_DIGITAL_INPUTS = 0x46; - private static final int TAG_INPUT_VOLTAGE1 = 0x50; - private static final int TAG_INPUT_VOLTAGE2 = 0x51; - private static final int TAG_INPUT_VOLTAGE3 = 0x52; - private static final int TAG_INPUT_VOLTAGE4 = 0x53; - private static final int TAG_XT1 = 0x60; - private static final int TAG_XT2 = 0x61; - private static final int TAG_XT3 = 0x62; - - private void sendReply(Channel channel, int checksum) { - if (channel != null) { - ByteBuf reply = Unpooled.buffer(3); - reply.writeByte(0x02); - reply.writeShortLE((short) checksum); - channel.writeAndFlush(new NetworkMessage(reply, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // header - int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; - - List<Position> positions = new LinkedList<>(); - Set<Integer> tags = new HashSet<>(); - boolean hasLocation = false; - Position position = new Position(getProtocolName()); - - while (buf.readerIndex() < length) { - - // Check if new message started - int tag = buf.readUnsignedByte(); - if (tags.contains(tag)) { - if (hasLocation && position.getFixTime() != null) { - positions.add(position); - } - tags.clear(); - hasLocation = false; - position = new Position(getProtocolName()); - } - tags.add(tag); - - switch (tag) { - - case TAG_IMEI: - getDeviceSession(channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); - break; - - case TAG_DATE: - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - break; - - case TAG_COORDINATES: - hasLocation = true; - position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00); - position.setLatitude(buf.readIntLE() / 1000000.0); - position.setLongitude(buf.readIntLE() / 1000000.0); - break; - - case TAG_SPEED_COURSE: - position.setSpeed(buf.readUnsignedShortLE() * 0.0539957); - position.setCourse(buf.readUnsignedShortLE() * 0.1); - break; - - case TAG_ALTITUDE: - position.setAltitude(buf.readShortLE()); - break; - - case TAG_STATUS: - 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); - } - position.set(Position.KEY_CHARGE, BitUtil.check(status, 2)); - break; - - case TAG_DIGITAL_INPUTS: - 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.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.readUnsignedShortLE() / 1000.0); - break; - - case TAG_INPUT_VOLTAGE2: - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() / 1000.0); - break; - - case TAG_INPUT_VOLTAGE3: - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE() / 1000.0); - break; - - case TAG_INPUT_VOLTAGE4: - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE() / 1000.0); - break; - - case TAG_XT1: - case TAG_XT2: - case TAG_XT3: - buf.skipBytes(16); - break; - - default: - break; - - } - } - - if (hasLocation && position.getFixTime() != null) { - positions.add(position); - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - sendReply(channel, buf.readUnsignedShortLE()); - - for (Position p : positions) { - p.setDeviceId(deviceSession.getDeviceId()); - } - - if (positions.isEmpty()) { - return null; - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/BoxProtocol.java b/src/org/traccar/protocol/BoxProtocol.java deleted file mode 100644 index dfea15938..000000000 --- a/src/org/traccar/protocol/BoxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class BoxProtocol extends BaseProtocol { - - public BoxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new BoxProtocolDecoder(BoxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/BoxProtocolDecoder.java b/src/org/traccar/protocol/BoxProtocolDecoder.java deleted file mode 100644 index 3635c29e5..000000000 --- a/src/org/traccar/protocol/BoxProtocolDecoder.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2014 - 2019 Anton Tananaev (anton@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.Protocol; -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.regex.Pattern; - -public class BoxProtocolDecoder extends BaseProtocolDecoder { - - public BoxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("L,") - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .text("G,") - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+.?d*),") // distance - .number("(d+),") // event - .number("(d+)") // status - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("H,")) { - - int index = sentence.indexOf(',', 2) + 1; - String id = sentence.substring(index, sentence.indexOf(',', index)); - getDeviceSession(channel, remoteAddress, id); - - } else if (sentence.startsWith("E,")) { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("A," + sentence.substring(2) + "\r", remoteAddress)); - } - - } else if (sentence.startsWith("L,")) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - position.set(Position.KEY_ODOMETER_TRIP, parser.nextDouble() * 1000); - position.set(Position.KEY_EVENT, parser.next()); - - int status = parser.nextInt(); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); - position.set(Position.KEY_MOTION, BitUtil.check(status, 1)); - position.setValid(!BitUtil.check(status, 2)); - position.set(Position.KEY_STATUS, status); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/C2stekProtocol.java b/src/org/traccar/protocol/C2stekProtocol.java deleted file mode 100644 index 804621fd3..000000000 --- a/src/org/traccar/protocol/C2stekProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class C2stekProtocol extends BaseProtocol { - - public C2stekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new C2stekProtocolDecoder(C2stekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/C2stekProtocolDecoder.java b/src/org/traccar/protocol/C2stekProtocolDecoder.java deleted file mode 100644 index 6a31cb2f4..000000000 --- a/src/org/traccar/protocol/C2stekProtocolDecoder.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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.Protocol; -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 C2stekProtocolDecoder extends BaseProtocolDecoder { - - public C2stekProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("PA$") - .number("(d+)") // imei - .text("$") - .expression(".#") // data type - .number("(dd)(dd)(dd)#") // date (yymmdd) - .number("(dd)(dd)(dd)#") // time (hhmmss) - .number("([01])#") // valid - .number("([+-]?d+.d+)#") // latitude - .number("([+-]?d+.d+)#") // longitude - .number("(d+.d+)#") // speed - .number("(d+.d+)#") // course - .number("(-?d+.d+)#") // altitude - .number("(d+)#") // battery - .number("d+#") // geo area alarm - .number("(x+)#") // alarm - .number("([01])") // armed - .number("([01])") // door - .number("([01])#") // ignition - .any() - .text("$AP") - .compile(); - - private String decodeAlarm(int alarm) { - switch (alarm) { - case 0x2: - return Position.ALARM_SHOCK; - case 0x3: - return Position.ALARM_POWER_CUT; - case 0x4: - return Position.ALARM_OVERSPEED; - case 0x5: - return Position.ALARM_SOS; - case 0x6: - return Position.ALARM_DOOR; - case 0xA: - return Position.ALARM_LOW_BATTERY; - case 0xB: - return Position.ALARM_FAULT; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - if (sentence.contains("$20$") && channel != null) { - channel.writeAndFlush(new NetworkMessage(sentence, 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()); - position.setValid(parser.nextInt() > 0); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); - position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt())); - - position.set(Position.KEY_ARMED, parser.nextInt() > 0); - position.set(Position.KEY_DOOR, parser.nextInt() > 0); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); - - return position; - } - -} diff --git a/src/org/traccar/protocol/CalAmpProtocol.java b/src/org/traccar/protocol/CalAmpProtocol.java deleted file mode 100644 index 232e72a8c..000000000 --- a/src/org/traccar/protocol/CalAmpProtocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * 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; - -public class CalAmpProtocol extends BaseProtocol { - - public CalAmpProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/org/traccar/protocol/CalAmpProtocolDecoder.java deleted file mode 100644 index 31416d7f1..000000000 --- a/src/org/traccar/protocol/CalAmpProtocolDecoder.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; - -public class CalAmpProtocolDecoder extends BaseProtocolDecoder { - - public CalAmpProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_NULL = 0; - public static final int MSG_ACK = 1; - public static final int MSG_EVENT_REPORT = 2; - public static final int MSG_ID_REPORT = 3; - public static final int MSG_USER_DATA = 4; - public static final int MSG_APP_DATA = 5; - public static final int MSG_CONFIG = 6; - public static final int MSG_UNIT_REQUEST = 7; - public static final int MSG_LOCATE_REPORT = 8; - public static final int MSG_USER_DATA_ACC = 9; - public static final int MSG_MINI_EVENT_REPORT = 10; - public static final int MSG_MINI_USER_DATA = 11; - - public static final int SERVICE_UNACKNOWLEDGED = 0; - public static final int SERVICE_ACKNOWLEDGED = 1; - public static final int SERVICE_RESPONSE = 2; - - private void sendResponse(Channel channel, SocketAddress remoteAddress, int type, int index, int result) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(10); - response.writeByte(SERVICE_RESPONSE); - response.writeByte(MSG_ACK); - response.writeShort(index); - response.writeByte(type); - response.writeByte(result); - response.writeByte(0); - response.writeMedium(0); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - private Position decodePosition(DeviceSession deviceSession, int type, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - if (type != MSG_MINI_EVENT_REPORT) { - buf.readUnsignedInt(); // fix time - } - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - if (type != MSG_MINI_EVENT_REPORT) { - position.setAltitude(buf.readInt() * 0.01); - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedInt())); - } - position.setCourse(buf.readShort()); - if (type == MSG_MINI_EVENT_REPORT) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - } - - if (type == MSG_MINI_EVENT_REPORT) { - position.set(Position.KEY_SATELLITES, buf.getUnsignedByte(buf.readerIndex()) & 0xf); - position.setValid((buf.readUnsignedByte() & 0x20) == 0); - } else { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.setValid((buf.readUnsignedByte() & 0x08) == 0); - } - - if (type != MSG_MINI_EVENT_REPORT) { - position.set("carrier", buf.readUnsignedShort()); - position.set(Position.KEY_RSSI, buf.readShort()); - } - - position.set("modem", buf.readUnsignedByte()); - - if (type != MSG_MINI_EVENT_REPORT) { - position.set(Position.KEY_HDOP, buf.readUnsignedByte()); - } - - int input = buf.readUnsignedByte(); - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - if (type != MSG_MINI_EVENT_REPORT) { - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - } - - if (type == MSG_EVENT_REPORT || type == MSG_MINI_EVENT_REPORT) { - if (type != MSG_MINI_EVENT_REPORT) { - buf.readUnsignedByte(); // event index - } - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - } - - int accType = BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 6); - int accCount = BitUtil.to(buf.readUnsignedByte(), 6); - - if (type != MSG_MINI_EVENT_REPORT) { - position.set("append", buf.readUnsignedByte()); - } - - if (accType == 1) { - buf.readUnsignedInt(); // threshold - buf.readUnsignedInt(); // mask - } - - for (int i = 0; i < accCount; i++) { - if (buf.readableBytes() >= 4) { - position.set("acc" + i, buf.readUnsignedInt()); - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (BitUtil.check(buf.getByte(buf.readerIndex()), 7)) { - - int content = buf.readUnsignedByte(); - - if (BitUtil.check(content, 0)) { - String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())); - getDeviceSession(channel, remoteAddress, id); - } - - if (BitUtil.check(content, 1)) { - buf.skipBytes(buf.readUnsignedByte()); // identifier type - } - - if (BitUtil.check(content, 2)) { - buf.skipBytes(buf.readUnsignedByte()); // authentication - } - - if (BitUtil.check(content, 3)) { - buf.skipBytes(buf.readUnsignedByte()); // routing - } - - if (BitUtil.check(content, 4)) { - buf.skipBytes(buf.readUnsignedByte()); // forwarding - } - - if (BitUtil.check(content, 5)) { - buf.skipBytes(buf.readUnsignedByte()); // response redirection - } - - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - int service = buf.readUnsignedByte(); - int type = buf.readUnsignedByte(); - int index = buf.readUnsignedShort(); - - if (service == SERVICE_ACKNOWLEDGED) { - sendResponse(channel, remoteAddress, type, index, 0); - } - - if (type == MSG_EVENT_REPORT || type == MSG_LOCATE_REPORT || type == MSG_MINI_EVENT_REPORT) { - return decodePosition(deviceSession, type, buf); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/CarTrackProtocol.java b/src/org/traccar/protocol/CarTrackProtocol.java deleted file mode 100644 index e340fba25..000000000 --- a/src/org/traccar/protocol/CarTrackProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class CarTrackProtocol extends BaseProtocol { - - public CarTrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new CarTrackProtocolDecoder(CarTrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/org/traccar/protocol/CarTrackProtocolDecoder.java deleted file mode 100644 index ce3345826..000000000 --- a/src/org/traccar/protocol/CarTrackProtocolDecoder.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) - * Copyright 2014 Rohit - * - * 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.Protocol; -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.util.regex.Pattern; - -public class CarTrackProtocolDecoder extends BaseProtocolDecoder { - - public CarTrackProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$$") // header - .number("(d+)") // device id - .text("?").expression("*") - .text("&A") - .number("(dddd)") // command - .text("&B") - .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(dd)(dd.dddd),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.dddd),") // longitude - .expression("([EW]),") - .number("(d+.d*)?,") // speed - .number("(d+.d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .expression("&C([^&]*)") // io - .expression("&D([^&]*)") // odometer - .expression("&E([^&]*)") // alarm - .expression("&Y([^&]*)").optional() // adc - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_COMMAND, parser.next()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set(Position.PREFIX_IO + 1, parser.next()); - - String odometer = parser.next(); - odometer = odometer.replace(":", "A"); - odometer = odometer.replace(";", "B"); - odometer = odometer.replace("<", "C"); - odometer = odometer.replace("=", "D"); - odometer = odometer.replace(">", "E"); - odometer = odometer.replace("?", "F"); - position.set(Position.KEY_ODOMETER, Integer.parseInt(odometer, 16)); - - parser.next(); // there is no meaningful alarms - position.set(Position.PREFIX_ADC + 1, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/CarcellProtocol.java b/src/org/traccar/protocol/CarcellProtocol.java deleted file mode 100644 index 0c305efcb..000000000 --- a/src/org/traccar/protocol/CarcellProtocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class CarcellProtocol extends BaseProtocol { - - public CarcellProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new CarcellProtocolEncoder()); - pipeline.addLast(new CarcellProtocolDecoder(CarcellProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java deleted file mode 100644 index 344b2f1ea..000000000 --- a/src/org/traccar/protocol/CarcellProtocolDecoder.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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. - * 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 java.net.SocketAddress; -import java.util.regex.Pattern; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.Parser.CoordinateFormat; -import org.traccar.helper.PatternBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -public class CarcellProtocolDecoder extends BaseProtocolDecoder { - - public CarcellProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("([$%])") // memory flag - .number("(d+),") // imei - .groupBegin() - .number("([NS])(dd)(dd).(dddd),") // latitude - .number("([EW])(ddd)(dd).(dddd),") // longitude - .or() - .text("CEL,") - .number("([NS])(d+.d+),") // latitude - .number("([EW])(d+.d+),") // longitude - .groupEnd() - .number("(d+),") // speed - .number("(d+),") // course - .groupBegin() - .number("([-+]ddd)([-+]ddd)([-+]ddd),") // x,y,z - .or() - .number("(d+),") // accel - .groupEnd() - .number("(d+),") // battery - .number("(d+),") // csq - .number("(d),") // jamming - .number("(d+),") // hdop - .expression("([CG]),?") // clock type - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d),") // block - .number("(d),") // ignition - .groupBegin() - .number("(d),") // cloned - .expression("([AF])") // panic - .number("(d),") // painel - .number("(d+),") // battery voltage - .or() - .number("(dd),") // time until delivery - .expression("([AF])") // panic - .number("(d),") // aux - .number("(d{2,4}),") // battery voltage - .number("(d{20}),") // ccid - .groupEnd() - .number("(xx)") // crc - .any() // full format - .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; - } - - Position position = new Position(getProtocolName()); - position.set(Position.KEY_ARCHIVE, parser.next().equals("%")); - position.setValid(true); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - if (parser.hasNext(8)) { - position.setLatitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG_MIN_MIN)); - position.setLongitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG_MIN_MIN)); - } - - if (parser.hasNext(4)) { - position.setLatitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG)); - } - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - - if (parser.hasNext(3)) { - position.set("x", parser.nextInt(0)); - position.set("y", parser.nextInt(0)); - position.set("z", parser.nextInt(0)); - } - - if (parser.hasNext(1)) { - position.set(Position.KEY_ACCELERATION, parser.nextInt(0)); - } - - Double internalBattery = (parser.nextDouble(0) + 100d) * 0.0294d; - position.set(Position.KEY_BATTERY, internalBattery); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set("jamming", parser.next().equals("1")); - position.set(Position.KEY_GPS, parser.nextInt(0)); - - position.set("clockType", parser.next()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.set("blocked", parser.next().equals("1")); - position.set(Position.KEY_IGNITION, parser.next().equals("1")); - - if (parser.hasNext(4)) { - position.set("cloned", parser.next().equals("1")); - - parser.next(); // panic button status - - String painelStatus = parser.next(); - if (painelStatus.equals("1")) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - position.set("painel", painelStatus.equals("2")); - - Double mainVoltage = parser.nextDouble(0) / 100d; - position.set(Position.KEY_POWER, mainVoltage); - } - - if (parser.hasNext(5)) { - position.set("timeUntilDelivery", parser.nextInt(0)); - parser.next(); // panic button status - position.set(Position.KEY_INPUT, parser.next()); - - Double mainVoltage = parser.nextDouble(0) / 100d; - position.set(Position.KEY_POWER, mainVoltage); - - position.set("iccid", parser.next()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/CarcellProtocolEncoder.java b/src/org/traccar/protocol/CarcellProtocolEncoder.java deleted file mode 100644 index e8f0081a0..000000000 --- a/src/org/traccar/protocol/CarcellProtocolEncoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.model.Command; - -public class CarcellProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "$SRVCMD,{%s},BA#\r\n", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "$SRVCMD,{%s},BD#\r\n", Command.KEY_UNIQUE_ID); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/CarscopProtocol.java b/src/org/traccar/protocol/CarscopProtocol.java deleted file mode 100644 index 2c754a97f..000000000 --- a/src/org/traccar/protocol/CarscopProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class CarscopProtocol extends BaseProtocol { - - public CarscopProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new CarscopProtocolDecoder(CarscopProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CarscopProtocolDecoder.java b/src/org/traccar/protocol/CarscopProtocolDecoder.java deleted file mode 100644 index 161666adc..000000000 --- a/src/org/traccar/protocol/CarscopProtocolDecoder.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class CarscopProtocolDecoder extends BaseProtocolDecoder { - - public CarscopProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*") - .any() - .number("(dd)(dd)(dd)") // time (hhmmss) - .expression("([AV])") // validity - .number("(dd)(dd.dddd)") // latitude - .expression("([NS])") - .number("(ddd)(dd.dddd)") // longitude - .expression("([EW])") - .number("(ddd.d)") // speed - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(ddd.dd)") // course - .groupBegin() - .number("(d{8})") // state - .number("L(d{6})") // odometer - .groupEnd("?") - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - DeviceSession deviceSession; - int index = sentence.indexOf("UB05"); - if (index != -1) { - String imei = sentence.substring(index + 4, index + 4 + 15); - deviceSession = getDeviceSession(channel, remoteAddress, imei); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - 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)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - - dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext(2)) { - position.set(Position.KEY_STATUS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/CastelProtocol.java b/src/org/traccar/protocol/CastelProtocol.java deleted file mode 100644 index 9b854afc3..000000000 --- a/src/org/traccar/protocol/CastelProtocol.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -import java.nio.ByteOrder; -public class CastelProtocol extends BaseProtocol { - - public CastelProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); - pipeline.addLast(new CastelProtocolEncoder()); - pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CastelProtocolEncoder()); - pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java deleted file mode 100644 index 0541adf6f..000000000 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ /dev/null @@ -1,573 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.ObdDecoder; -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.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class CastelProtocolDecoder extends BaseProtocolDecoder { - - private static final Map<Integer, Integer> PID_LENGTH_MAP = new HashMap<>(); - - static { - int[] l1 = { - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0b, 0x0d, - 0x0e, 0x0f, 0x11, 0x12, 0x13, 0x1c, 0x1d, 0x1e, 0x2c, - 0x2d, 0x2e, 0x2f, 0x30, 0x33, 0x43, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x51, 0x52, - 0x5a - }; - int[] l2 = { - 0x02, 0x03, 0x0a, 0x0c, 0x10, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1f, 0x21, 0x22, - 0x23, 0x31, 0x32, 0x3c, 0x3d, 0x3e, 0x3f, 0x42, - 0x44, 0x4d, 0x4e, 0x50, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59 - }; - int[] l4 = { - 0x00, 0x01, 0x20, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x2b, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x3b, 0x40, 0x41, 0x4f - }; - for (int i : l1) { - PID_LENGTH_MAP.put(i, 1); - } - for (int i : l2) { - PID_LENGTH_MAP.put(i, 2); - } - for (int i : l4) { - PID_LENGTH_MAP.put(i, 4); - } - } - - public CastelProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final short MSG_SC_LOGIN = 0x1001; - public static final short MSG_SC_LOGIN_RESPONSE = (short) 0x9001; - public static final short MSG_SC_LOGOUT = 0x1002; - public static final short MSG_SC_HEARTBEAT = 0x1003; - public static final short MSG_SC_HEARTBEAT_RESPONSE = (short) 0x9003; - public static final short MSG_SC_GPS = 0x4001; - public static final short MSG_SC_PID_DATA = 0x4002; - public static final short MSG_SC_SUPPORTED_PID = 0x4004; - public static final short MSG_SC_OBD_DATA = 0x4005; - public static final short MSG_SC_DTCS_PASSENGER = 0x4006; - public static final short MSG_SC_DTCS_COMMERCIAL = 0x400B; - public static final short MSG_SC_ALARM = 0x4007; - public static final short MSG_SC_CELL = 0x4008; - 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; - public static final short MSG_CC_LOGIN_RESPONSE = (short) 0x8001; - public static final short MSG_CC_HEARTBEAT = 0x4206; - public static final short MSG_CC_PETROL_CONTROL = 0x4583; - public static final short MSG_CC_HEARTBEAT_RESPONSE = (short) 0x8206; - - private Position readPosition(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - 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) { - lat = -lat; - } - if ((flags & 0x01) == 0) { - lon = -lon; - } - position.setLatitude(lat); - position.setLongitude(lon); - position.setValid((flags & 0x0C) > 0); - position.set(Position.KEY_SATELLITES, flags >> 4); - - return position; - } - - private Position createPosition(DeviceSession deviceSession) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - return position; - } - - 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.readUnsignedShortLE() & 0xff; - } - - if (groups) { - buf.readUnsignedByte(); // group count - buf.readUnsignedByte(); // group size - } - - for (int i = 0; i < count; i++) { - int value; - switch (PID_LENGTH_MAP.get(pids[i])) { - case 1: - value = buf.readUnsignedByte(); - break; - case 2: - value = buf.readUnsignedShortLE(); - break; - case 4: - value = buf.readIntLE(); - break; - default: - value = 0; - break; - } - position.add(ObdDecoder.decodeData(pids[i], value, false)); - } - } - - private void decodeStat(Position position, ByteBuf buf) { - - 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, ByteBuf id, short type, ByteBuf content) { - - if (channel != null) { - int length = 2 + 2 + 1 + id.readableBytes() + 2 + 2 + 2; - if (content != null) { - length += content.readableBytes(); - } - - ByteBuf response = Unpooled.buffer(length); - response.writeByte('@'); response.writeByte('@'); - response.writeShortLE(length); - response.writeByte(version); - response.writeBytes(id); - response.writeShort(type); - if (content != null) { - response.writeBytes(content); - content.release(); - } - response.writeShortLE( - Checksum.crc16(Checksum.CRC16_X25, response.nioBuffer(0, response.writerIndex()))); - response.writeByte(0x0D); response.writeByte(0x0A); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - private void sendResponse( - Channel channel, SocketAddress remoteAddress, ByteBuf id, short type) { - - if (channel != null) { - int length = 2 + 2 + id.readableBytes() + 2 + 4 + 8 + 2 + 2; - - ByteBuf response = Unpooled.buffer(length); - response.writeByte('@'); response.writeByte('@'); - response.writeShortLE(length); - response.writeBytes(id); - response.writeShort(type); - response.writeIntLE(0); - for (int i = 0; i < 8; i++) { - response.writeByte(0xff); - } - response.writeShortLE( - Checksum.crc16(Checksum.CRC16_X25, response.nioBuffer(0, response.writerIndex()))); - response.writeByte(0x0D); response.writeByte(0x0A); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - private void decodeAlarm(Position position, int alarm) { - switch (alarm) { - case 0x01: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 0x02: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 0x03: - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case 0x04: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - 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; - case 0x0E: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case 0x16: - position.set(Position.KEY_IGNITION, true); - break; - case 0x17: - position.set(Position.KEY_IGNITION, false); - break; - default: - break; - } - } - - private Object decodeSc( - Channel channel, SocketAddress remoteAddress, ByteBuf buf, - int version, ByteBuf id, short type, DeviceSession deviceSession) { - - if (type == MSG_SC_HEARTBEAT) { - - sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null); - - } else if (type == MSG_SC_LOGIN || type == MSG_SC_LOGOUT || type == MSG_SC_GPS - || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION || type == MSG_SC_FUEL) { - - if (type == MSG_SC_LOGIN) { - 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.readUnsignedIntLE(); // alarm - } else if (type == MSG_SC_CURRENT_LOCATION) { - buf.readUnsignedShortLE(); - } - - 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(); - - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < count; i++) { - Position position = readPosition(deviceSession, buf); - position.set(Position.KEY_ODOMETER, odometer); - position.set(Position.KEY_ODOMETER_TRIP, tripOdometer); - position.set(Position.KEY_FUEL_CONSUMPTION, fuelConsumption); - position.set(Position.KEY_STATUS, status); - positions.add(position); - } - - if (type == MSG_SC_ALARM) { - int alarmCount = buf.readUnsignedByte(); - for (int i = 0; i < alarmCount; i++) { - if (buf.readUnsignedByte() != 0) { - int alarm = buf.readUnsignedByte(); - for (Position position : positions) { - decodeAlarm(position, alarm); - } - buf.readUnsignedShortLE(); // description - buf.readUnsignedShortLE(); // threshold - } - } - } else if (type == MSG_SC_FUEL) { - for (Position position : positions) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - } - } - - if (!positions.isEmpty()) { - return positions; - } - - } else if (type == MSG_SC_GPS_SLEEP) { - - buf.readUnsignedIntLE(); // device time - - return readPosition(deviceSession, buf); - - } else if (type == MSG_SC_AGPS_REQUEST) { - - return readPosition(deviceSession, buf); - - } else if (type == MSG_SC_PID_DATA) { - - Position position = createPosition(deviceSession); - - decodeStat(position, buf); - - buf.readUnsignedShortLE(); // sample rate - decodeObd(position, buf, true); - - return position; - - } else if (type == MSG_SC_DTCS_PASSENGER) { - - Position position = createPosition(deviceSession); - - decodeStat(position, buf); - - buf.readUnsignedByte(); // flag - position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())))); - - return position; - - } else if (type == MSG_SC_OBD_DATA) { - - Position position = createPosition(deviceSession); - - decodeStat(position, buf); - - buf.readUnsignedByte(); // flag - decodeObd(position, buf, false); - - return position; - - } else if (type == MSG_SC_CELL) { - - Position position = createPosition(deviceSession); - - decodeStat(position, buf); - - position.setNetwork(new Network( - 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; - - } - - return null; - } - - private Object decodeCc( - Channel channel, SocketAddress remoteAddress, ByteBuf buf, - int version, ByteBuf id, short type, DeviceSession deviceSession) { - - if (type == MSG_CC_HEARTBEAT) { - - sendResponse(channel, remoteAddress, version, id, MSG_CC_HEARTBEAT_RESPONSE, null); - - buf.readUnsignedByte(); // 0x01 for history - int count = buf.readUnsignedByte(); - - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < count; i++) { - Position position = readPosition(deviceSession, buf); - - position.set(Position.KEY_STATUS, buf.readUnsignedIntLE()); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - 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.readUnsignedShortLE(), buf.readUnsignedShortLE()))); - - positions.add(position); - } - - return positions; - - } else if (type == MSG_CC_LOGIN) { - - sendResponse(channel, remoteAddress, version, id, MSG_CC_LOGIN_RESPONSE, null); - - Position position = readPosition(deviceSession, buf); - - position.set(Position.KEY_STATUS, buf.readUnsignedIntLE()); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - - buf.readUnsignedByte(); // geo-fencing id - buf.readUnsignedByte(); // geo-fencing flags - buf.readUnsignedByte(); // additional flags - - // GSM_CELL_CODE - // STR_Z - firmware version - // STR_Z - hardware version - - return position; - - } - - return null; - } - - private Object decodeMpip( - Channel channel, SocketAddress remoteAddress, ByteBuf buf, - int version, ByteBuf id, short type, DeviceSession deviceSession) { - - if (type == 0x4001) { - - sendResponse(channel, remoteAddress, version, id, (short) type, null); - - return readPosition(deviceSession, buf); - - } else if (type == 0x2001) { - - sendResponse(channel, remoteAddress, id, (short) 0x1001); - - buf.readUnsignedIntLE(); // index - buf.readUnsignedIntLE(); // unix time - buf.readUnsignedByte(); - - return readPosition(deviceSession, buf); - - } else if (type == 0x4201 || type == 0x4202 || type == 0x4206) { - - return readPosition(deviceSession, buf); - - } else if (type == 0x4204) { - - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < 8; i++) { - Position position = readPosition(deviceSession, buf); - buf.skipBytes(31); - positions.add(position); - } - - return positions; - - } - - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int header = buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); // length - - int version = -1; - if (header == 0x4040) { - version = buf.readUnsignedByte(); - } - - ByteBuf id = buf.readSlice(20); - short type = buf.readShort(); - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, id.toString(StandardCharsets.US_ASCII).trim()); - if (deviceSession == null) { - return null; - } - - switch (version) { - case -1: - return decodeMpip(channel, remoteAddress, buf, version, id, type, deviceSession); - case 3: - case 4: - return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); - default: - return decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession); - } - } - -} diff --git a/src/org/traccar/protocol/CastelProtocolEncoder.java b/src/org/traccar/protocol/CastelProtocolEncoder.java deleted file mode 100644 index e1f78e7c1..000000000 --- a/src/org/traccar/protocol/CastelProtocolEncoder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.Context; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class CastelProtocolEncoder extends BaseProtocolEncoder { - - 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.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(type); - buf.writeBytes(content); - - buf.writeShortLE(Checksum.crc16(Checksum.CRC16_X25, buf.nioBuffer())); - - buf.writeByte('\r'); - buf.writeByte('\n'); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - ByteBuf content = Unpooled.buffer(0); - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - content.writeByte(1); - return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); - case Command.TYPE_ENGINE_RESUME: - content.writeByte(0); - return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/CautelaProtocol.java b/src/org/traccar/protocol/CautelaProtocol.java deleted file mode 100644 index 452bdf8d4..000000000 --- a/src/org/traccar/protocol/CautelaProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class CautelaProtocol extends BaseProtocol { - - public CautelaProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new CautelaProtocolDecoder(CautelaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CautelaProtocolDecoder.java b/src/org/traccar/protocol/CautelaProtocolDecoder.java deleted file mode 100644 index bddf19b41..000000000 --- a/src/org/traccar/protocol/CautelaProtocolDecoder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.Protocol; -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.util.regex.Pattern; - -public class CautelaProtocolDecoder extends BaseProtocolDecoder { - - public CautelaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // type - .number("(d+),") // imei - .number("(dd),(dd),(dd),") // date (ddmmyy) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(dd)(dd),") // time (hhmm) - .any() - .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; - } - - parser.next(); // type - - 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(); - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setValid(true); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - - dateBuilder.setHour(parser.nextInt()).setMinute(parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/CellocatorFrameDecoder.java b/src/org/traccar/protocol/CellocatorFrameDecoder.java deleted file mode 100644 index 7d5499d92..000000000 --- a/src/org/traccar/protocol/CellocatorFrameDecoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - * 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 CellocatorFrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_MINIMUM_LENGTH = 15; - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - int length = 0; - int type = buf.getUnsignedByte(4); - switch (type) { - case CellocatorProtocolDecoder.MSG_CLIENT_STATUS: - length = 70; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_PROGRAMMING: - length = 31; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL_LOG: - length = 70; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL: - if (buf.readableBytes() >= 19) { - length = 19 + buf.getUnsignedShortLE(16); - } - break; - case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR: - length = 15 + buf.getUnsignedByte(13); - break; - default: - break; - } - - 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 deleted file mode 100644 index a52170dc9..000000000 --- a/src/org/traccar/protocol/CellocatorProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class CellocatorProtocol extends BaseProtocol { - - public CellocatorProtocol() { - setSupportedDataCommands( - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CellocatorFrameDecoder()); - pipeline.addLast(new CellocatorProtocolEncoder()); - pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CellocatorProtocolEncoder()); - pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/org/traccar/protocol/CellocatorProtocolDecoder.java deleted file mode 100644 index d23f76a93..000000000 --- a/src/org/traccar/protocol/CellocatorProtocolDecoder.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2013 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class CellocatorProtocolDecoder extends BaseProtocolDecoder { - - public CellocatorProtocolDecoder(Protocol protocol) { - super(protocol); - } - - static final int MSG_CLIENT_STATUS = 0; - static final int MSG_CLIENT_PROGRAMMING = 3; - static final int MSG_CLIENT_SERIAL_LOG = 7; - static final int MSG_CLIENT_SERIAL = 8; - static final int MSG_CLIENT_MODULAR = 9; - - public static final int MSG_SERVER_ACKNOWLEDGE = 4; - - private byte commandCount; - - private void sendReply(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) { - if (channel != null) { - 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)); - } - } - - private String decodeAlarm(short reason) { - switch (reason) { - case 70: - return Position.ALARM_SOS; - case 80: - return Position.ALARM_POWER_CUT; - case 81: - return Position.ALARM_LOW_POWER; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - boolean alternative = buf.getByte(buf.readerIndex() + 3) != 'P'; - - buf.skipBytes(4); // system code - int type = buf.readUnsignedByte(); - long deviceUniqueId = buf.readUnsignedIntLE(); - - if (type != MSG_CLIENT_SERIAL) { - buf.readUnsignedShortLE(); // communication control - } - byte packetNumber = buf.readByte(); - - sendReply(channel, remoteAddress, deviceUniqueId, packetNumber); - - if (type == MSG_CLIENT_STATUS) { - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceUniqueId)); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - buf.readUnsignedByte(); // protocol version - - position.set(Position.KEY_STATUS, buf.readUnsignedByte() & 0x0f); - - buf.readUnsignedByte(); // operator / configuration flags - buf.readUnsignedByte(); // reason data - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - - position.set("mode", buf.readUnsignedByte()); - position.set(Position.KEY_INPUT, buf.readUnsignedIntLE()); - - if (alternative) { - buf.readUnsignedByte(); // input - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); - } else { - buf.readUnsignedByte(); // operator - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedIntLE()); - } - - position.set(Position.KEY_ODOMETER, buf.readUnsignedMediumLE()); - - buf.skipBytes(6); // multi-purpose data - buf.readUnsignedShortLE(); // fix time - buf.readUnsignedByte(); // location status - buf.readUnsignedByte(); // mode 1 - buf.readUnsignedByte(); // mode 2 - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - position.setValid(true); - - if (alternative) { - position.setLongitude(buf.readIntLE() / 10000000.0); - position.setLatitude(buf.readIntLE() / 10000000.0); - } else { - position.setLongitude(buf.readIntLE() / Math.PI * 180 / 100000000); - position.setLatitude(buf.readIntLE() / Math.PI * 180 / 100000000); - } - - position.setAltitude(buf.readIntLE() * 0.01); - - if (alternative) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedIntLE())); - position.setCourse(buf.readUnsignedShortLE() / 1000.0); - } else { - position.setSpeed(UnitsConverter.knotsFromMps(buf.readUnsignedIntLE() * 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.readUnsignedShortLE()); - position.setTime(dateBuilder.getDate()); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/org/traccar/protocol/CellocatorProtocolEncoder.java deleted file mode 100644 index 0382dbbc7..000000000 --- a/src/org/traccar/protocol/CellocatorProtocolEncoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.model.Command; - -public class CellocatorProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(long deviceId, int command, int data1, int data2) { - - ByteBuf buf = Unpooled.buffer(0); - buf.writeByte('M'); - buf.writeByte('C'); - buf.writeByte('G'); - buf.writeByte('P'); - buf.writeByte(0); - buf.writeIntLE(Integer.parseInt(getUniqueId(deviceId))); - buf.writeByte(0); // command numerator - buf.writeIntLE(0); // authentication code - buf.writeByte(command); - buf.writeByte(command); - buf.writeByte(data1); - buf.writeByte(data1); - buf.writeByte(data2); - buf.writeByte(data2); - buf.writeIntLE(0); // command specific data - - byte checksum = 0; - for (int i = 4; i < buf.writerIndex(); i++) { - checksum += buf.getByte(i); - } - buf.writeByte(checksum); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_OUTPUT_CONTROL: - int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4 - + command.getInteger(Command.KEY_INDEX); - return encodeContent(command.getDeviceId(), 0x03, data, 0); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/CguardProtocol.java b/src/org/traccar/protocol/CguardProtocol.java deleted file mode 100644 index 9157ca35c..000000000 --- a/src/org/traccar/protocol/CguardProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class CguardProtocol extends BaseProtocol { - - public CguardProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new CguardProtocolDecoder(CguardProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CguardProtocolDecoder.java b/src/org/traccar/protocol/CguardProtocolDecoder.java deleted file mode 100644 index d934921f1..000000000 --- a/src/org/traccar/protocol/CguardProtocolDecoder.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 CguardProtocolDecoder extends BaseProtocolDecoder { - - public CguardProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_NV = new PatternBuilder() - .text("NV:") - .number("(dd)(dd)(dd) ") // date (yymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .number(":(-?d+.d+)") // longitude - .number(":(-?d+.d+)") // latitude - .number(":(d+.?d*)") // speed - .number(":(?:NAN|(d+.?d*))") // accuracy - .number(":(?:NAN|(d+.?d*))") // course - .number(":(?:NAN|(d+.?d*))").optional() // altitude - .compile(); - - private static final Pattern PATTERN_BC = new PatternBuilder() - .text("BC:") - .number("(dd)(dd)(dd) ") // date (yymmdd) - .number("(dd)(dd)(dd):") // time (hhmmss) - .expression("(.+)") // data - .compile(); - - private Position decodePosition(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN_NV, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setValid(true); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - - position.setAccuracy(parser.nextDouble(0)); - - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - return position; - } - - private Position decodeStatus(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN_BC, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, parser.nextDateTime()); - - String[] data = parser.next().split(":"); - for (int i = 0; i < data.length / 2; i++) { - String key = data[i * 2]; - String value = data[i * 2 + 1]; - switch (key) { - case "CSQ1": - position.set(Position.KEY_RSSI, Integer.parseInt(value)); - break; - case "NSQ1": - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case "BAT1": - if (value.contains(".")) { - position.set(Position.KEY_BATTERY, Double.parseDouble(value)); - } else { - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value)); - } - break; - case "PWR1": - position.set(Position.KEY_POWER, Double.parseDouble(value)); - break; - default: - position.set(key.toLowerCase(), value); - break; - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("ID:") || sentence.startsWith("IDRO:")) { - getDeviceSession(channel, remoteAddress, sentence.substring(sentence.indexOf(':') + 1)); - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (sentence.startsWith("NV:")) { - return decodePosition(deviceSession, sentence); - } else if (sentence.startsWith("BC:")) { - return decodeStatus(deviceSession, sentence); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/CityeasyProtocol.java b/src/org/traccar/protocol/CityeasyProtocol.java deleted file mode 100644 index f4b49c9ff..000000000 --- a/src/org/traccar/protocol/CityeasyProtocol.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class CityeasyProtocol extends BaseProtocol { - - public CityeasyProtocol() { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_POSITION_STOP, - Command.TYPE_SET_TIMEZONE); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); - pipeline.addLast(new CityeasyProtocolEncoder()); - pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/org/traccar/protocol/CityeasyProtocolDecoder.java deleted file mode 100644 index 9c4c7e11d..000000000 --- a/src/org/traccar/protocol/CityeasyProtocolDecoder.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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. - * 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.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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.regex.Pattern; - -public class CityeasyProtocolDecoder extends BaseProtocolDecoder { - - public CityeasyProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .groupBegin() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("([AV]),") // validity - .number("(d+),") // satellites - .number("([NS]),(d+.d+),") // latitude - .number("([EW]),(d+.d+),") // longitude - .number("(d+.d),") // speed - .number("(d+.d),") // hdop - .number("(d+.d)") // altitude - .groupEnd("?").text(";") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(d+),") // lac - .number("(d+)") // cell - .any() - .compile(); - - public static final int MSG_ADDRESS_REQUEST = 0x0001; - public static final int MSG_STATUS = 0x0002; - public static final int MSG_LOCATION_REPORT = 0x0003; - public static final int MSG_LOCATION_REQUEST = 0x0004; - public static final int MSG_LOCATION_INTERVAL = 0x0005; - public static final int MSG_PHONE_NUMBER = 0x0006; - public static final int MSG_MONITORING = 0x0007; - public static final int MSG_TIMEZONE = 0x0008; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedShort(); // length - - String imei = ByteBufUtil.hexDump(buf.readSlice(7)); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, imei, imei + Checksum.luhn(Long.parseLong(imei))); - if (deviceSession == null) { - return null; - } - - int type = buf.readUnsignedShort(); - - if (type == MSG_LOCATION_REPORT || type == MSG_LOCATION_REQUEST) { - - String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 8, StandardCharsets.US_ASCII); - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (parser.hasNext(15)) { - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - - position.setSpeed(parser.nextDouble(0)); - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - } else { - - getLastLocation(position, null); - - } - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)))); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/org/traccar/protocol/CityeasyProtocolEncoder.java deleted file mode 100644 index 350fdf0ab..000000000 --- a/src/org/traccar/protocol/CityeasyProtocolEncoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - * 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 java.util.TimeZone; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -public class CityeasyProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(int type, ByteBuf content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte('S'); - buf.writeByte('S'); - buf.writeShort(2 + 2 + 2 + content.readableBytes() + 4 + 2 + 2); - buf.writeShort(type); - buf.writeBytes(content); - buf.writeInt(0x0B); - buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.nioBuffer())); - buf.writeByte('\r'); - buf.writeByte('\n'); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - ByteBuf content = Unpooled.buffer(); - - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_REQUEST, content); - case Command.TYPE_POSITION_PERIODIC: - content.writeShort(command.getInteger(Command.KEY_FREQUENCY)); - return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); - case Command.TYPE_POSITION_STOP: - content.writeShort(0); - return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); - case Command.TYPE_SET_TIMEZONE: - int timezone = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; - if (timezone < 0) { - content.writeByte(1); - } else { - content.writeByte(0); - } - content.writeShort(Math.abs(timezone)); - return encodeContent(CityeasyProtocolDecoder.MSG_TIMEZONE, content); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/ContinentalProtocol.java b/src/org/traccar/protocol/ContinentalProtocol.java deleted file mode 100644 index bc7928fba..000000000 --- a/src/org/traccar/protocol/ContinentalProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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; - -public class ContinentalProtocol extends BaseProtocol { - - public ContinentalProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); - pipeline.addLast(new ContinentalProtocolDecoder(ContinentalProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/org/traccar/protocol/ContinentalProtocolDecoder.java deleted file mode 100644 index 471afa0d6..000000000 --- a/src/org/traccar/protocol/ContinentalProtocolDecoder.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; - -public class ContinentalProtocolDecoder extends BaseProtocolDecoder { - - public ContinentalProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_KEEPALIVE = 0x00; - public static final int MSG_STATUS = 0x02; - public static final int MSG_ACK = 0x06; - public static final int MSG_NACK = 0x15; - - private double readCoordinate(ByteBuf buf, boolean extended) { - long value = buf.readUnsignedInt(); - if (extended ? (value & 0x08000000) != 0 : (value & 0x00800000) != 0) { - value |= extended ? 0xF0000000 : 0xFF000000; - } - return (int) value / (extended ? 360000.0 : 3600.0); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // software version - - long serialNumber = buf.readUnsignedInt(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(serialNumber)); - if (deviceSession == null) { - return null; - } - - buf.readUnsignedByte(); // product - - int type = buf.readUnsignedByte(); - - if (type == MSG_STATUS) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setFixTime(new Date(buf.readUnsignedInt() * 1000L)); - - boolean extended = buf.getUnsignedByte(buf.readerIndex()) != 0; - position.setLatitude(readCoordinate(buf, extended)); - position.setLongitude(readCoordinate(buf, extended)); - - position.setCourse(buf.readUnsignedShort()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - - position.setValid(buf.readUnsignedByte() > 0); - - position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000L)); - - position.set(Position.KEY_EVENT, 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; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/CradlepointProtocol.java b/src/org/traccar/protocol/CradlepointProtocol.java deleted file mode 100644 index 4a09e0311..000000000 --- a/src/org/traccar/protocol/CradlepointProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class CradlepointProtocol extends BaseProtocol { - - public CradlepointProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new CradlepointProtocolDecoder(CradlepointProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java deleted file mode 100644 index a282131ce..000000000 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.Date; -import java.util.regex.Pattern; - -public class CradlepointProtocolDecoder extends BaseProtocolDecoder { - - public CradlepointProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("([^,]+),") // id - .number("(d{1,6}),") // time (hhmmss) - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .expression("([^,]+)?,") // carrier - .expression("([^,]+)?,") // serdis - .number("(-?d+)?,") // rsrp - .number("(-?d+)?,") // rssi - .number("(-?d+)?,") // rsrq - .expression("([^,]+)?,") // ecio - .expression("([^,]+)?") // wan ip - .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()); - - int time = parser.nextInt(); - DateBuilder dateBuilder = new DateBuilder(new Date()); - dateBuilder.setHour(time / 100 / 100); - dateBuilder.setMinute(time / 100 % 100); - dateBuilder.setSecond(time % 100); - position.setTime(dateBuilder.getDate()); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set("carrid", parser.next()); - position.set("serdis", 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 deleted file mode 100644 index 38f49cc05..000000000 --- a/src/org/traccar/protocol/DishaProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class DishaProtocol extends BaseProtocol { - - public DishaProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new DishaProtocolDecoder(DishaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/DishaProtocolDecoder.java b/src/org/traccar/protocol/DishaProtocolDecoder.java deleted file mode 100644 index 3223988ab..000000000 --- a/src/org/traccar/protocol/DishaProtocolDecoder.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class DishaProtocolDecoder extends BaseProtocolDecoder { - - public DishaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$A#A#") - .number("(d+)#") // imei - .expression("([AVMX])#") // validity - .number("(dd)(dd)(dd)#") // time (hhmmss) - .number("(dd)(dd)(dd)#") // date (ddmmyy) - .number("(dd)(dd.d+)#") // latitude - .expression("([NS])#") - .number("(ddd)(dd.d+)#") // longitude - .expression("([EW])#") - .number("(d+.d+)#") // speed - .number("(d+.d+)#") // course - .number("(d+)#") // satellites - .number("(d+.d+)#") // hdop - .number("(d+)#") // gsm - .expression("([012])#") // power mode - .number("(d+)#") // battery - .number("(d+)#") // adc 1 - .number("(d+)#") // adc 2 - .number("d+.d+#") // day distance - .number("(d+.d+)#") // odometer - .expression("([01]+)") // digital inputs - .text("*") - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.next().equals("A")); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_RSSI, parser.nextDouble()); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 2); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 2, parser.nextInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_INPUT, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/DmtHttpProtocol.java b/src/org/traccar/protocol/DmtHttpProtocol.java deleted file mode 100644 index 34568128f..000000000 --- a/src/org/traccar/protocol/DmtHttpProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class DmtHttpProtocol extends BaseProtocol { - - public DmtHttpProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); - pipeline.addLast(new DmtHttpProtocolDecoder(DmtHttpProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java deleted file mode 100644 index 987361baf..000000000 --- a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.LinkedList; -import java.util.List; -import java.util.TimeZone; - -public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { - - public DmtHttpProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - JsonObject root = Json.createReader( - new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); - - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, root.getString("IMEI")); - if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - - List<Position> positions = new LinkedList<>(); - - JsonArray records = root.getJsonArray("Records"); - - for (int i = 0; i < records.size(); i++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - JsonObject record = records.getJsonObject(i); - - position.set(Position.KEY_INDEX, record.getInt("SeqNo")); - position.set(Position.KEY_EVENT, record.getInt("Reason")); - - position.setDeviceTime(dateFormat.parse(record.getString("DateUTC"))); - - JsonArray fields = record.getJsonArray("Fields"); - - for (int j = 0; j < fields.size(); j++) { - JsonObject field = fields.getJsonObject(j); - switch (field.getInt("FType")) { - case 0: - position.setFixTime(dateFormat.parse(field.getString("GpsUTC"))); - position.setLatitude(field.getJsonNumber("Lat").doubleValue()); - position.setLongitude(field.getJsonNumber("Long").doubleValue()); - position.setAltitude(field.getInt("Alt")); - position.setSpeed(UnitsConverter.knotsFromCps(field.getInt("Spd"))); - position.setCourse(field.getInt("Head")); - position.setAccuracy(field.getInt("PosAcc")); - position.setValid(field.getInt("GpsStat") > 0); - break; - case 2: - int input = field.getInt("DIn"); - int output = field.getInt("DOut"); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - position.set(Position.KEY_STATUS, field.getInt("DevStat")); - break; - case 6: - JsonObject adc = field.getJsonObject("AnalogueData"); - if (adc.containsKey("1")) { - position.set(Position.KEY_BATTERY, adc.getInt("1") * 0.001); - } - if (adc.containsKey("2")) { - position.set(Position.KEY_POWER, adc.getInt("2") * 0.01); - } - if (adc.containsKey("3")) { - position.set(Position.KEY_DEVICE_TEMP, adc.getInt("3") * 0.01); - } - if (adc.containsKey("4")) { - position.set(Position.KEY_RSSI, adc.getInt("4")); - } - if (adc.containsKey("5")) { - position.set("solarPower", adc.getInt("5") * 0.001); - } - break; - default: - break; - } - } - - positions.add(position); - } - - sendResponse(channel, HttpResponseStatus.OK); - return positions; - } - -} diff --git a/src/org/traccar/protocol/DmtProtocol.java b/src/org/traccar/protocol/DmtProtocol.java deleted file mode 100644 index 78a5243c0..000000000 --- a/src/org/traccar/protocol/DmtProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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; -public class DmtProtocol extends BaseProtocol { - - public DmtProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); - pipeline.addLast(new DmtProtocolDecoder(DmtProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java deleted file mode 100644 index c04e90f1d..000000000 --- a/src/org/traccar/protocol/DmtProtocolDecoder.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.charset.StandardCharsets; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class DmtProtocolDecoder extends BaseProtocolDecoder { - - public DmtProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_HELLO = 0x00; - public static final int MSG_HELLO_RESPONSE = 0x01; - public static final int MSG_DATA_RECORD = 0x04; - public static final int MSG_COMMIT = 0x05; - public static final int MSG_COMMIT_RESPONSE = 0x06; - public static final int MSG_DATA_RECORD_64 = 0x10; - - public static final int MSG_CANNED_REQUEST_1 = 0x14; - public static final int MSG_CANNED_RESPONSE_1 = 0x15; - 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, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(0x02); response.writeByte(0x55); // header - response.writeByte(type); - response.writeShortLE(content != null ? content.readableBytes() : 0); - if (content != null) { - response.writeBytes(content); - content.release(); - } - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private List<Position> decodeFixed64(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() >= 64) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readByte(); // type - - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - - long time = buf.readUnsignedIntLE(); - position.setTime(new DateBuilder() - .setYear((int) (2000 + (time & 0x3F))) - .setMonth((int) (time >> 6) & 0xF) - .setDay((int) (time >> 10) & 0x1F) - .setHour((int) (time >> 15) & 0x1F) - .setMinute((int) (time >> 20) & 0x3F) - .setSecond((int) (time >> 26) & 0x3F) - .getDate()); - - 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.readShortLE()); - - 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.readUnsignedIntLE()); - position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); - - for (int i = 1; i <= 5; i++) { - position.set(Position.PREFIX_ADC + i, buf.readShortLE()); - } - - position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - - buf.readShortLE(); // accelerometer x - buf.readShortLE(); // accelerometer y - buf.readShortLE(); // accelerometer z - - buf.skipBytes(8); // device id - - position.set(Position.KEY_PDOP, buf.readUnsignedShortLE() * 0.01); - - buf.skipBytes(2); // reserved - - buf.readUnsignedShortLE(); // checksum - - positions.add(position); - } - - return positions; - } - - private List<Position> decodeStandard(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.isReadable()) { - int recordEnd = buf.readerIndex() + buf.readUnsignedShortLE(); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - - position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedIntLE() * 1000)); // since 1 Jan 2013 - - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - while (buf.readerIndex() < recordEnd) { - - int fieldId = buf.readUnsignedByte(); - int fieldLength = buf.readUnsignedByte(); - int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShortLE() : fieldLength); - - if (fieldId == 0) { - - 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 - - position.setCourse(buf.readUnsignedByte() * 2); - - position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); - - position.setAccuracy(buf.readUnsignedByte()); - position.setValid(buf.readUnsignedByte() != 0); - - } else if (fieldId == 2) { - - int input = buf.readIntLE(); - int output = buf.readUnsignedShortLE(); - int status = buf.readUnsignedShortLE(); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - position.set(Position.KEY_STATUS, status); - - } else if (fieldId == 6) { - - while (buf.readerIndex() < fieldEnd) { - switch (buf.readUnsignedByte()) { - case 1: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - break; - case 2: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); - break; - case 3: - position.set(Position.KEY_DEVICE_TEMP, buf.readShortLE() * 0.01); - break; - case 4: - position.set(Position.KEY_RSSI, buf.readUnsignedShortLE()); - break; - case 5: - position.set("solarPower", buf.readUnsignedShortLE() * 0.001); - break; - default: - break; - } - } - - } - - buf.readerIndex(fieldEnd); - - } - - if (position.getFixTime() == null) { - getLastLocation(position, position.getDeviceTime()); - } - - positions.add(position); - } - - return positions; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - - int type = buf.readUnsignedByte(); - int length = buf.readUnsignedShortLE(); - - if (type == MSG_HELLO) { - - buf.readUnsignedIntLE(); // device serial number - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); - - ByteBuf response = Unpooled.buffer(); - if (length == 51) { - response.writeByte(0); // reserved - response.writeIntLE(0); // reserved - } else { - 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) { - - ByteBuf response = Unpooled.buffer(0); - response.writeByte(1); // flags (success) - sendResponse(channel, MSG_COMMIT_RESPONSE, response); - - } else if (type == MSG_CANNED_REQUEST_1) { - - ByteBuf response = Unpooled.buffer(0); - response.writeBytes(new byte[12]); - sendResponse(channel, MSG_CANNED_RESPONSE_1, response); - - } else if (type == MSG_CANNED_REQUEST_2) { - - sendResponse(channel, MSG_CANNED_RESPONSE_2, null); - - } else if (type == MSG_DATA_RECORD_64) { - - return decodeFixed64(channel, remoteAddress, buf); - - } else if (type == MSG_DATA_RECORD) { - - return decodeStandard(channel, remoteAddress, buf); - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/DwayProtocol.java b/src/org/traccar/protocol/DwayProtocol.java deleted file mode 100644 index 05fd8b6e7..000000000 --- a/src/org/traccar/protocol/DwayProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class DwayProtocol extends BaseProtocol { - - public DwayProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new DwayProtocolDecoder(DwayProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/DwayProtocolDecoder.java b/src/org/traccar/protocol/DwayProtocolDecoder.java deleted file mode 100644 index 9b02c898e..000000000 --- a/src/org/traccar/protocol/DwayProtocolDecoder.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 DwayProtocolDecoder extends BaseProtocolDecoder { - - public DwayProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("AA55,") - .number("d+,") // index - .number("(d+),") // imei - .number("d+,") // type - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(-?d+),") // altitude - .number(" ?(d+.d+),") // speed - .number("(d+),") // course - .number("([01]{4}),") // input - .number("([01]{4}),") // output - .number("([01]+),") // flags - .number("(d+),") // battery - .number("(d+),") // adc1 - .number("(d+),") // adc2 - .number("(d+)") // driver - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - if (sentence.equals("AA55,HB")) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("55AA,HB,OK\r\n", remoteAddress)); - } - return null; - } - - 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.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_INPUT, parser.nextBinInt()); - position.set(Position.KEY_OUTPUT, parser.nextBinInt()); - - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); - position.set(Position.PREFIX_ADC + 1, parser.nextInt() * 0.001); - position.set(Position.PREFIX_ADC + 2, parser.nextInt() * 0.001); - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/EasyTrackProtocol.java b/src/org/traccar/protocol/EasyTrackProtocol.java deleted file mode 100644 index 74c636d06..000000000 --- a/src/org/traccar/protocol/EasyTrackProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class EasyTrackProtocol extends BaseProtocol { - - public EasyTrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#", "\r\n")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new EasyTrackProtocolDecoder(EasyTrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java deleted file mode 100644 index 2ddb24f5c..000000000 --- a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -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 EasyTrackProtocolDecoder extends BaseProtocolDecoder { - - public EasyTrackProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*").expression("..,") // manufacturer - .number("(d+),") // imei - .expression("([^,]{2}),") // command - .expression("([AV]),") // validity - .number("(xx)(xx)(xx),") // date (yymmdd) - .number("(xx)(xx)(xx),") // time (hhmmss) - .number("(x)(x{7}),") // latitude - .number("(x)(x{7}),") // longitude - .number("(x{4}),") // speed - .number("(x{4}),") // course - .number("(x{8}),") // status - .number("(x+),") // signal - .number("(d+),") // power - .number("(x{4}),") // oil - .number("(x+),?") // odometer - .number("(d+)?") // altitude - .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 { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_COMMAND, parser.next()); - - position.setValid(parser.next().equals("A")); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextHexInt(0), parser.nextHexInt(0), parser.nextHexInt(0)) - .setTime(parser.nextHexInt(0), parser.nextHexInt(0), parser.nextHexInt(0)); - position.setTime(dateBuilder.getDate()); - - if (BitUtil.check(parser.nextHexInt(0), 3)) { - position.setLatitude(-parser.nextHexInt(0) / 600000.0); - } else { - position.setLatitude(parser.nextHexInt(0) / 600000.0); - } - - if (BitUtil.check(parser.nextHexInt(0), 3)) { - position.setLongitude(-parser.nextHexInt(0) / 600000.0); - } else { - position.setLongitude(parser.nextHexInt(0) / 600000.0); - } - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt(0) / 100.0)); - position.setCourse(parser.nextHexInt(0) / 100.0); - - 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)); - position.set(Position.KEY_ODOMETER, parser.nextHexInt(0) * 100); - - position.setAltitude(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/EelinkProtocol.java b/src/org/traccar/protocol/EelinkProtocol.java deleted file mode 100644 index de4ea971b..000000000 --- a/src/org/traccar/protocol/EelinkProtocol.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class EelinkProtocol extends BaseProtocol { - - public EelinkProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); - pipeline.addLast(new EelinkProtocolEncoder(false)); - pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EelinkProtocolEncoder(true)); - pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java deleted file mode 100644 index 2a1db2e32..000000000 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ /dev/null @@ -1,441 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.socket.DatagramChannel; -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.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.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.regex.Pattern; - -public class EelinkProtocolDecoder extends BaseProtocolDecoder { - - public EelinkProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN = 0x01; - public static final int MSG_GPS = 0x02; - public static final int MSG_HEARTBEAT = 0x03; - public static final int MSG_ALARM = 0x04; - public static final int MSG_STATE = 0x05; - public static final int MSG_SMS = 0x06; - public static final int MSG_OBD = 0x07; - public static final int MSG_DOWNLINK = 0x80; - public static final int MSG_DATA = 0x81; - - public static final int MSG_NORMAL = 0x12; - public static final int MSG_WARNING = 0x14; - public static final int MSG_REPORT = 0x15; - public static final int MSG_COMMAND = 0x16; - public static final int MSG_OBD_DATA = 0x17; - public static final int MSG_OBD_BODY = 0x18; - public static final int MSG_OBD_CODE = 0x19; - public static final int MSG_CAMERA_INFO = 0x1E; - public static final int MSG_CAMERA_DATA = 0x1F; - - private String decodeAlarm(Short value) { - switch (value) { - case 0x01: - return Position.ALARM_POWER_OFF; - case 0x02: - return Position.ALARM_SOS; - case 0x03: - return Position.ALARM_LOW_BATTERY; - case 0x04: - return Position.ALARM_VIBRATION; - case 0x08: - case 0x09: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x81: - return Position.ALARM_LOW_SPEED; - case 0x82: - return Position.ALARM_OVERSPEED; - case 0x83: - return Position.ALARM_GEOFENCE_ENTER; - case 0x84: - return Position.ALARM_GEOFENCE_EXIT; - case 0x85: - return Position.ALARM_ACCIDENT; - case 0x86: - return Position.ALARM_FALL_DOWN; - default: - return null; - } - } - - private void decodeStatus(Position position, int status) { - if (BitUtil.check(status, 1)) { - position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); - } - if (BitUtil.check(status, 3)) { - position.set(Position.KEY_ARMED, BitUtil.check(status, 4)); - } - if (BitUtil.check(status, 5)) { - position.set(Position.KEY_BLOCKED, !BitUtil.check(status, 6)); - } - if (BitUtil.check(status, 7)) { - position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); - } - position.set(Position.KEY_STATUS, status); - } - - private Position decodeOld(DeviceSession deviceSession, ByteBuf buf, int type, int index) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, index); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.setLatitude(buf.readInt() / 1800000.0); - position.setLongitude(buf.readInt() / 1800000.0); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedShort()); - - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); - - position.setValid((buf.readUnsignedByte() & 0x01) != 0); - - if (type == MSG_GPS) { - - if (buf.readableBytes() >= 2) { - decodeStatus(position, buf.readUnsignedShort()); - } - - if (buf.readableBytes() >= 2 * 4) { - - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - - position.set(Position.KEY_RSSI, buf.readUnsignedShort()); - - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - - } - - } else if (type == MSG_ALARM) { - - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - - } else if (type == MSG_STATE) { - - int statusType = buf.readUnsignedByte(); - - position.set(Position.KEY_EVENT, statusType); - - if (statusType == 0x01 || statusType == 0x02 || statusType == 0x03) { - buf.readUnsignedInt(); // device time - if (buf.readableBytes() >= 2) { - decodeStatus(position, buf.readUnsignedShort()); - } - } - - } - - return position; - } - - private Position decodeNew(DeviceSession deviceSession, ByteBuf buf, int type, int index) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, index); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - int flags = buf.readUnsignedByte(); - - if (BitUtil.check(flags, 0)) { - position.setLatitude(buf.readInt() / 1800000.0); - position.setLongitude(buf.readInt() / 1800000.0); - position.setAltitude(buf.readShort()); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - position.setCourse(buf.readUnsignedShort()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - } else { - getLastLocation(position, position.getDeviceTime()); - } - - if (BitUtil.check(flags, 1)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte()))); - } - - if (BitUtil.check(flags, 2)) { - buf.skipBytes(7); // bsid1 - } - - if (BitUtil.check(flags, 3)) { - buf.skipBytes(7); // bsid2 - } - - if (BitUtil.check(flags, 4)) { - buf.skipBytes(7); // bss0 - } - - if (BitUtil.check(flags, 5)) { - buf.skipBytes(7); // bss1 - } - - if (BitUtil.check(flags, 6)) { - buf.skipBytes(7); // bss2 - } - - 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 (type == MSG_NORMAL) { - - 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 (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() >= 2) { - position.set(Position.PREFIX_TEMP + 2, buf.readShort() / 16.0); - } - - } - - return position; - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("Lat:") - .number("([NS])(d+.d+)") // latitude - .any() - .text("Lon:") - .number("([EW])(d+.d+)") // longitude - .any() - .text("Course:") - .number("(d+.d+)") // course - .any() - .text("Speed:") - .number("(d+.d+)") // speed - .any() - .expression("Date ?Time:") - .number("(dddd)-(dd)-(dd) ") // date - .number("(dd):(dd):(dd)") // time - .compile(); - - private Position decodeResult(DeviceSession deviceSession, ByteBuf buf, int index) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, index); - - buf.readUnsignedByte(); // type - buf.readUnsignedInt(); // uid - - String sentence = buf.toString(StandardCharsets.UTF_8); - - Parser parser = new Parser(PATTERN, sentence); - if (parser.matches()) { - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setCourse(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setTime(parser.nextDateTime()); - - } else { - - getLastLocation(position, null); - - position.set(Position.KEY_RESULT, sentence); - - } - - return position; - } - - private Position decodeObd(DeviceSession deviceSession, ByteBuf buf, int index) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, new Date(buf.readUnsignedInt() * 1000)); - - while (buf.readableBytes() > 0) { - int pid = buf.readUnsignedByte(); - int value = buf.readInt(); - switch (pid) { - case 0x89: - position.set(Position.KEY_FUEL_CONSUMPTION, value); - break; - case 0x8a: - position.set(Position.KEY_ODOMETER, value * 1000L); - break; - case 0x8b: - position.set(Position.KEY_FUEL_LEVEL, value / 10); - break; - default: - break; - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - 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 = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - - buf.skipBytes(2); // header - int type = buf.readUnsignedByte(); - buf.readShort(); // length - int index = buf.readUnsignedShort(); - - if (type != MSG_GPS && type != MSG_DATA) { - ByteBuf content = Unpooled.buffer(); - if (type == MSG_LOGIN) { - content.writeInt((int) (System.currentTimeMillis() / 1000)); - content.writeByte(1); // protocol version - content.writeByte(0); // action mask - } - ByteBuf response = EelinkProtocolEncoder.encodeContent( - channel instanceof DatagramChannel, uniqueId, type, index, content); - content.release(); - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - if (type == MSG_LOGIN) { - - if (deviceSession == null) { - getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(buf.readSlice(8)).substring(1)); - } - - } else { - - if (deviceSession == null) { - return null; - } - - if (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS) { - - return decodeOld(deviceSession, buf, type, index); - - } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) { - - return decodeNew(deviceSession, buf, type, index); - - } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - decodeStatus(position, buf.readUnsignedShort()); - - return position; - - } else if (type == MSG_OBD) { - - return decodeObd(deviceSession, buf, index); - - } else if (type == MSG_DOWNLINK) { - - return decodeResult(deviceSession, buf, index); - - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java deleted file mode 100644 index 8f33441fb..000000000 --- a/src/org/traccar/protocol/EelinkProtocolEncoder.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -public class EelinkProtocolEncoder extends BaseProtocolEncoder { - - private boolean connectionless; - - public EelinkProtocolEncoder(boolean connectionless) { - this.connectionless = connectionless; - } - - public static int checksum(ByteBuffer buf) { - int sum = 0; - while (buf.hasRemaining()) { - sum = (((sum << 1) | (sum >> 15)) + (buf.get() & 0xFF)) & 0xFFFF; - } - return sum; - } - - public static ByteBuf encodeContent( - boolean connectionless, String uniqueId, int type, int index, ByteBuf content) { - - ByteBuf buf = Unpooled.buffer(); - - if (connectionless) { - buf.writeBytes(DataConverter.parseHex('0' + uniqueId)); - } - - buf.writeByte(0x67); - buf.writeByte(0x67); - buf.writeByte(type); - buf.writeShort(2 + (content != null ? content.readableBytes() : 0)); // length - buf.writeShort(index); - - if (content != null) { - buf.writeBytes(content); - } - - ByteBuf result = Unpooled.buffer(); - - if (connectionless) { - result.writeByte('E'); - result.writeByte('L'); - result.writeShort(2 + buf.readableBytes()); // length - result.writeShort(checksum(buf.nioBuffer())); - } - - result.writeBytes(buf); - buf.release(); - - return result; - } - - private ByteBuf encodeContent(long deviceId, String content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte(0x01); // command - buf.writeInt(0); // server id - buf.writeBytes(content.getBytes(StandardCharsets.UTF_8)); - - return encodeContent(connectionless, getUniqueId(deviceId), EelinkProtocolDecoder.MSG_DOWNLINK, 0, buf); - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), "WHERE#"); - case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), "RELAY,1#"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), "RELAY,0#"); - case Command.TYPE_REBOOT_DEVICE: - return encodeContent(command.getDeviceId(), "RESET#"); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/EgtsFrameDecoder.java b/src/org/traccar/protocol/EgtsFrameDecoder.java deleted file mode 100644 index 84f1f11a7..000000000 --- a/src/org/traccar/protocol/EgtsFrameDecoder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 EgtsFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - int headerLength = buf.getUnsignedByte(buf.readerIndex() + 3); - int frameLength = buf.getUnsignedShortLE(buf.readerIndex() + 5); - - int length = headerLength + frameLength + (frameLength > 0 ? 2 : 0); - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/EgtsProtocol.java b/src/org/traccar/protocol/EgtsProtocol.java deleted file mode 100644 index 5d4638f37..000000000 --- a/src/org/traccar/protocol/EgtsProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - -public class EgtsProtocol extends BaseProtocol { - - public EgtsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EgtsFrameDecoder()); - pipeline.addLast(new EgtsProtocolDecoder(EgtsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EgtsProtocolDecoder.java b/src/org/traccar/protocol/EgtsProtocolDecoder.java deleted file mode 100644 index b9fcb2f44..000000000 --- a/src/org/traccar/protocol/EgtsProtocolDecoder.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * 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.Protocol; -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; - -public class EgtsProtocolDecoder extends BaseProtocolDecoder { - - public EgtsProtocolDecoder(Protocol protocol) { - 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; - public static final int SERVICE_FIRMWARE = 9; - public static final int SERVICE_ECALL = 10; - - public static final int MSG_RECORD_RESPONSE = 0; - public static final int MSG_TERM_IDENTITY = 1; - public static final int MSG_MODULE_DATA = 2; - public static final int MSG_VEHICLE_DATA = 3; - public static final int MSG_AUTH_PARAMS = 4; - public static final int MSG_AUTH_INFO = 5; - public static final int MSG_SERVICE_INFO = 6; - public static final int MSG_RESULT_CODE = 7; - public static final int MSG_POS_DATA = 16; - public static final int MSG_EXT_POS_DATA = 17; - public static final int MSG_AD_SENSORS_DATA = 18; - public static final int MSG_COUNTERS_DATA = 19; - public static final int MSG_STATE_DATA = 20; - public static final int MSG_LOOPIN_DATA = 22; - public static final int MSG_ABS_DIG_SENS_DATA = 23; - public static final int MSG_ABS_AN_SENS_DATA = 24; - public static final int MSG_ABS_CNTR_DATA = 25; - public static final int MSG_ABS_LOOPIN_DATA = 26; - 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 { - - ByteBuf buf = (ByteBuf) msg; - - int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); - buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3)); - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() > 2) { - - int length = buf.readUnsignedShortLE(); - int recordIndex = buf.readUnsignedShortLE(); - int recordFlags = buf.readUnsignedByte(); - - if (BitUtil.check(recordFlags, 0)) { - buf.readUnsignedIntLE(); // object id - } - - if (BitUtil.check(recordFlags, 1)) { - buf.readUnsignedIntLE(); // event id - } - if (BitUtil.check(recordFlags, 2)) { - buf.readUnsignedIntLE(); // time - } - - int serviceType = buf.readUnsignedByte(); - buf.readUnsignedByte(); // recipient service type - - int recordEnd = buf.readerIndex() + length; - - Position position = new Position(getProtocolName()); - 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.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()); - } - - response = Unpooled.buffer(); - response.writeByte(0); // success - sendResponse(channel, PT_APPDATA, 0, serviceType, MSG_RESULT_CODE, response); - - } 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)); - if (BitUtil.check(flags, 5)) { - position.setLatitude(-position.getLatitude()); - } - if (BitUtil.check(flags, 6)) { - position.setLongitude(-position.getLongitude()); - } - - 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.readUnsignedMediumLE() * 100); - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - if (BitUtil.check(flags, 7)) { - position.setAltitude(buf.readMediumLE()); - } - - } else if (type == MSG_EXT_POS_DATA) { - - int flags = buf.readUnsignedByte(); - - if (BitUtil.check(flags, 0)) { - position.set(Position.KEY_VDOP, buf.readUnsignedShortLE()); - } - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); - } - if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_PDOP, buf.readUnsignedShortLE()); - } - if (BitUtil.check(flags, 3)) { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - } - - } else if (type == MSG_AD_SENSORS_DATA) { - - buf.readUnsignedByte(); // inputs flags - - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // adc flags - - } - - buf.readerIndex(end); - } - - 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 deleted file mode 100644 index f78e4b377..000000000 --- a/src/org/traccar/protocol/EnforaProtocol.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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 org.traccar.model.Command; - -public class EnforaProtocol extends BaseProtocol { - - public EnforaProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); - pipeline.addLast(new EnforaProtocolEncoder()); - pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EnforaProtocolEncoder()); - pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EnforaProtocolDecoder.java b/src/org/traccar/protocol/EnforaProtocolDecoder.java deleted file mode 100644 index bfa7a116b..000000000 --- a/src/org/traccar/protocol/EnforaProtocolDecoder.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BufferUtil; -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 EnforaProtocolDecoder extends BaseProtocolDecoder { - - public EnforaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .any() - .compile(); - - public static final int IMEI_LENGTH = 15; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - // Find IMEI number - 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; - } - } - if (index > 0) { - break; - } - } - if (index == -1) { - return null; - } - - String imei = buf.toString(index, IMEI_LENGTH, StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - // Find NMEA sentence - int start = BufferUtil.indexOf("GPRMC", buf); - if (start == -1) { - return null; - } - - String sentence = buf.toString(start, buf.readableBytes() - start, StandardCharsets.US_ASCII); - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - 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)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/EnforaProtocolEncoder.java b/src/org/traccar/protocol/EnforaProtocolEncoder.java deleted file mode 100644 index a46e6367d..000000000 --- a/src/org/traccar/protocol/EnforaProtocolEncoder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Jose Castellanos - * - * 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 org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class EnforaProtocolEncoder extends StringProtocolEncoder { - - private ByteBuf encodeContent(String content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeShort(content.length() + 6); - buf.writeShort(0); // index - buf.writeByte(0x04); // command type - buf.writeByte(0); // optional header - buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command.getString(Command.KEY_DATA)); - case Command.TYPE_ENGINE_STOP: - return encodeContent("AT$IOGP3=1"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent("AT$IOGP3=0"); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/EsealProtocol.java b/src/org/traccar/protocol/EsealProtocol.java deleted file mode 100644 index 7a27c617d..000000000 --- a/src/org/traccar/protocol/EsealProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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; - -public class EsealProtocol extends BaseProtocol { - - public EsealProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new EsealProtocolEncoder()); - pipeline.addLast(new EsealProtocolDecoder(EsealProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EsealProtocolDecoder.java b/src/org/traccar/protocol/EsealProtocolDecoder.java deleted file mode 100644 index 7a1fd7022..000000000 --- a/src/org/traccar/protocol/EsealProtocolDecoder.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index b9bcc5b0a..000000000 --- a/src/org/traccar/protocol/EsealProtocolEncoder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.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: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/EskyFrameDecoder.java b/src/org/traccar/protocol/EskyFrameDecoder.java deleted file mode 100644 index da24c1273..000000000 --- a/src/org/traccar/protocol/EskyFrameDecoder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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 EskyFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - 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.readRetainedSlice(endIndex - buf.readerIndex()); - } else { - return buf.readRetainedSlice(buf.readableBytes()); // assume full frame - } - } - -} diff --git a/src/org/traccar/protocol/EskyProtocol.java b/src/org/traccar/protocol/EskyProtocol.java deleted file mode 100644 index aaa92da58..000000000 --- a/src/org/traccar/protocol/EskyProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class EskyProtocol extends BaseProtocol { - - public EskyProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EskyFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java deleted file mode 100644 index 641b2e28f..000000000 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 EskyProtocolDecoder extends BaseProtocolDecoder { - - public EskyProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("..;") // header - .number("d+;") // index - .number("(d+);") // imei - .text("R;") // data type - .number("(d+)[+;]") // satellites - .number("(dd)(dd)(dd)") // date - .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(); - - @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.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setValid(true); - position.setTime(parser.nextDateTime()); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromMps(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - 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 deleted file mode 100644 index 692fd4e99..000000000 --- a/src/org/traccar/protocol/ExtremTracProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class ExtremTracProtocol extends BaseProtocol { - - public ExtremTracProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new ExtremTracProtocolDecoder(ExtremTracProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/org/traccar/protocol/ExtremTracProtocolDecoder.java deleted file mode 100644 index 9fde6f0a0..000000000 --- a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class ExtremTracProtocolDecoder extends BaseProtocolDecoder { - - public ExtremTracProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$GPRMC,") - .number("(d+),") // device id - .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .any() - .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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/FifotrackProtocol.java b/src/org/traccar/protocol/FifotrackProtocol.java deleted file mode 100644 index 371e01e55..000000000 --- a/src/org/traccar/protocol/FifotrackProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class FifotrackProtocol extends BaseProtocol { - - public FifotrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new FifotrackProtocolDecoder(FifotrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java deleted file mode 100644 index beaa34125..000000000 --- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.DataConverter; -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 FifotrackProtocolDecoder extends BaseProtocolDecoder { - - private ByteBuf photo; - - public FifotrackProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$$") - .number("d+,") // length - .number("(d+),") // imei - .number("x+,") // index - .expression("[^,]+,") // type - .number("(d+)?,") // alarm - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("([AV]),") // validity - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(-?d+),") // altitude - .number("(d+),") // odometer - .number("d+,") // runtime - .number("(xxxx),") // status - .number("(x+)?,") // input - .number("(x+)?,") // output - .number("(d+)|") // mcc - .number("(d+)|") // mnc - .number("(x+)|") // lac - .number("(x+),") // cid - .number("([x|]+)") // adc - .expression(",([^,]+)") // rfid - .expression(",([^*]+)").optional(2) // sensors - .any() - .compile(); - - private static final Pattern PATTERN_PHOTO = new PatternBuilder() - .text("$$") - .number("d+,") // length - .number("(d+),") // imei - .any() - .number(",(d+),") // length - .expression("([^*]+)") // photo id - .text("*") - .number("xx") - .compile(); - - private static final Pattern PATTERN_PHOTO_DATA = new PatternBuilder() - .text("$$") - .number("d+,") // length - .number("(d+),") // imei - .expression("([^*]+),") // photo id - .number("(d+),") // offset - .number("(d+),") // size - .number("(x+)") // data - .text("*") - .number("xx") - .compile(); - - private void requestPhoto(Channel channel, SocketAddress socketAddress, String imei, String file) { - if (channel != null) { - String content = "D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); - int length = 1 + imei.length() + 1 + content.length() + 5; - String response = String.format("@@%02d,%s,%s*", length, imei, content); - response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); - } - } - - private Object decodeLocation( - Channel channel, SocketAddress remoteAddress, String sentence) { - - 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()); - - position.set(Position.KEY_ALARM, parser.next()); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - position.setAltitude(parser.nextInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextLong(0)); - position.set(Position.KEY_STATUS, parser.nextHexInt(0)); - if (parser.hasNext()) { - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - } - if (parser.hasNext()) { - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); - } - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - - String[] adc = parser.next().split("\\|"); - for (int i = 0; i < adc.length; i++) { - position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16)); - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - if (parser.hasNext()) { - String[] sensors = parser.next().split("\\|"); - for (int i = 0; i < sensors.length; i++) { - position.set(Position.PREFIX_IO + (i + 1), sensors[i]); - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - int typeIndex = sentence.indexOf(',', sentence.indexOf(',', sentence.indexOf(',') + 1) + 1) + 1; - String type = sentence.substring(typeIndex, typeIndex + 3); - - if (type.equals("D05")) { - Parser parser = new Parser(PATTERN_PHOTO, sentence); - if (parser.matches()) { - String imei = parser.next(); - int length = parser.nextInt(); - String photoId = parser.next(); - photo = Unpooled.buffer(length); - requestPhoto(channel, remoteAddress, imei, photoId); - } - } else if (type.equals("D06")) { - Parser parser = new Parser(PATTERN_PHOTO_DATA, sentence); - if (parser.matches()) { - String imei = parser.next(); - String photoId = parser.next(); - parser.nextInt(); // offset - parser.nextInt(); // size - photo.writeBytes(DataConverter.parseHex(parser.next())); - requestPhoto(channel, remoteAddress, imei, photoId); - } - } else { - return decodeLocation(channel, remoteAddress, sentence); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/FlespiProtocol.java b/src/org/traccar/protocol/FlespiProtocol.java deleted file mode 100644 index 2c0729b76..000000000 --- a/src/org/traccar/protocol/FlespiProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.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; - -public class FlespiProtocol extends BaseProtocol { - - public FlespiProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); - pipeline.addLast(new FlespiProtocolDecoder(FlespiProtocol.this)); - } - }); - } -} diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java deleted file mode 100644 index 86da3943e..000000000 --- a/src/org/traccar/protocol/FlespiProtocolDecoder.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; -import java.io.StringReader; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { - - public FlespiProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - 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++) { - JsonObject message = result.getJsonObject(i); - JsonString ident = message.getJsonString("ident"); - if (ident == null) { - continue; - } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident.getString()); - if (deviceSession == null) { - continue; - } - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - decodePosition(message, position); - positions.add(position); - } - - sendResponse(channel, HttpResponseStatus.OK); - return positions; - } - - private void decodePosition(JsonObject object, Position position) { - for (Map.Entry<String, JsonValue> param : object.entrySet()) { - String paramName = param.getKey(); - JsonValue paramValue = param.getValue(); - int index = -1; - if (paramName.contains("#")) { - String[] parts = paramName.split("#"); - paramName = parts[0]; - index = Integer.parseInt(parts[1]); - } - if (!decodeParam(paramName, index, paramValue, position)) { - decodeUnknownParam(param.getKey(), param.getValue(), position); - } - } - if (position.getLatitude() == 0 && position.getLongitude() == 0) { - getLastLocation(position, position.getDeviceTime()); - } - } - - private boolean decodeParam(String name, int index, JsonValue value, Position position) { - switch (name) { - case "timestamp": - position.setTime(new Date(((JsonNumber) value).longValue() * 1000)); - return true; - case "position.latitude": - position.setLatitude(((JsonNumber) value).doubleValue()); - return true; - case "position.longitude": - position.setLongitude(((JsonNumber) value).doubleValue()); - return true; - case "position.speed": - position.setSpeed(((JsonNumber) value).doubleValue()); - return true; - case "position.direction": - position.setCourse(((JsonNumber) value).doubleValue()); - return true; - case "position.altitude": - position.setAltitude(((JsonNumber) value).doubleValue()); - return true; - case "position.satellites": - position.set(Position.KEY_SATELLITES, ((JsonNumber) value).intValue()); - return true; - case "position.valid": - position.setValid(value == JsonValue.TRUE); - return true; - case "position.hdop": - position.set(Position.KEY_HDOP, ((JsonNumber) value).doubleValue()); - return true; - case "position.pdop": - position.set(Position.KEY_PDOP, ((JsonNumber) value).doubleValue()); - return true; - case "din": - case "dout": - position.set(name.equals("din") ? Position.KEY_INPUT : Position.KEY_OUTPUT, - ((JsonNumber) value).intValue()); - return true; - case "gps.vehicle.mileage": - position.set(Position.KEY_ODOMETER, ((JsonNumber) value).doubleValue()); - return true; - case "external.powersource.voltage": - position.set(Position.KEY_POWER, ((JsonNumber) value).doubleValue()); - return true; - case "battery.voltage": - position.set(Position.KEY_BATTERY, ((JsonNumber) value).doubleValue()); - return true; - case "fuel.level": - case "can.fuel.level": - position.set(Position.KEY_FUEL_LEVEL, ((JsonNumber) value).doubleValue()); - return true; - case "engine.rpm": - case "can.engine.rpm": - position.set(Position.KEY_RPM, ((JsonNumber) value).doubleValue()); - return true; - case "can.engine.temperature": - position.set(Position.PREFIX_TEMP + (index > 0 ? index : 0), ((JsonNumber) value).doubleValue()); - return true; - case "engine.ignition.status": - position.set(Position.KEY_IGNITION, value == JsonValue.TRUE); - return true; - case "movement.status": - position.set(Position.KEY_MOTION, value == JsonValue.TRUE); - return true; - case "device.temperature": - position.set(Position.KEY_DEVICE_TEMP, ((JsonNumber) value).doubleValue()); - return true; - case "ibutton.code": - position.set(Position.KEY_DRIVER_UNIQUE_ID, ((JsonString) value).getString()); - return true; - case "vehicle.vin": - position.set(Position.KEY_VIN, ((JsonString) value).getString()); - return true; - case "alarm.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - return true; - case "towing.event.trigger": - case "towing.alarm.status": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - } - return true; - case "geofence.event.enter": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); - } - return true; - case "geofence.event.exit": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); - } - return true; - case "shock.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); - } - return true; - case "overspeeding.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - return true; - case "harsh.acceleration.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - } - return true; - case "harsh.braking.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - } - return true; - case "harsh.cornering.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - } - return true; - case "gnss.antenna.cut.status": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); - } - return true; - case "gsm.jamming.event.trigger": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); - } - return true; - case "hood.open.status": - if (value == JsonValue.TRUE) { - position.set(Position.KEY_ALARM, Position.ALARM_BONNET); - } - return true; - default: - return false; - } - } - - private void decodeUnknownParam(String name, JsonValue value, Position position) { - if (value instanceof JsonNumber) { - if (((JsonNumber) value).isIntegral()) { - position.set(name, ((JsonNumber) value).longValue()); - } else { - position.set(name, ((JsonNumber) value).doubleValue()); - } - position.set(name, ((JsonNumber) value).doubleValue()); - } else if (value instanceof JsonString) { - position.set(name, ((JsonString) value).getString()); - } else if (value == JsonValue.TRUE || value == JsonValue.FALSE) { - position.set(name, value == JsonValue.TRUE); - } - } - -} diff --git a/src/org/traccar/protocol/FlexCommProtocol.java b/src/org/traccar/protocol/FlexCommProtocol.java deleted file mode 100644 index 9343ebeb8..000000000 --- a/src/org/traccar/protocol/FlexCommProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class FlexCommProtocol extends BaseProtocol { - - public FlexCommProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new FlexCommProtocolDecoder(FlexCommProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/org/traccar/protocol/FlexCommProtocolDecoder.java deleted file mode 100644 index 068c0a05c..000000000 --- a/src/org/traccar/protocol/FlexCommProtocolDecoder.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 FlexCommProtocolDecoder extends BaseProtocolDecoder { - - public FlexCommProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("7E") - .number("(dd)") // status - .number("(d{15})") // imei - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .expression("([01])") // valid - .number("(d{9})") // latitude - .number("(d{10})") // longitude - .number("(d{4})") // altitude - .number("(ddd)") // speed - .number("(ddd)") // course - .number("(dd)") // satellites view - .number("(dd)") // satellites used - .number("(dd)") // rssi - .number("(ddd)") // mcc - .number("(ddd)") // mnc - .number("(x{6})") // lac - .number("(x{6})") // cid - .expression("([01])([01])([01])") // input - .expression("([01])([01])") // output - .number("(ddd)") // fuel - .number("(d{4})") // temperature - .number("(ddd)") // battery - .number("(ddd)") // power - .any() - .compile(); - - private static double parseSignedValue(Parser parser, int decimalPoints) { - String stringValue = parser.next(); - boolean negative = stringValue.charAt(0) == '1'; - double value = Integer.parseInt(stringValue.substring(1)) * Math.pow(10, -decimalPoints); - return negative ? -value : value; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - position.set(Position.KEY_STATUS, parser.nextInt()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - position.setValid(parser.next().equals("1")); - position.setLatitude(parseSignedValue(parser, 6)); - position.setLongitude(parseSignedValue(parser, 6)); - position.setAltitude(parseSignedValue(parser, 0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextInt()); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt()))); - - for (int i = 1; i <= 3; i++) { - position.set(Position.PREFIX_IN + i, parser.nextInt()); - } - - for (int i = 1; i <= 2; i++) { - position.set(Position.PREFIX_OUT + i, parser.nextInt()); - } - - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parseSignedValue(parser, 0)); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_POWER, parser.nextInt() * 0.1); - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("{01}", remoteAddress)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/FlextrackProtocol.java b/src/org/traccar/protocol/FlextrackProtocol.java deleted file mode 100644 index ddd1d58f0..000000000 --- a/src/org/traccar/protocol/FlextrackProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class FlextrackProtocol extends BaseProtocol { - - public FlextrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new FlextrackProtocolDecoder(FlextrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/org/traccar/protocol/FlextrackProtocolDecoder.java deleted file mode 100644 index 9dce22ede..000000000 --- a/src/org/traccar/protocol/FlextrackProtocolDecoder.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 FlextrackProtocolDecoder extends BaseProtocolDecoder { - - public FlextrackProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_LOGON = new PatternBuilder() - .number("(-?d+),") // index - .text("LOGON,") - .number("(d+),") // node id - .number("(d+)") // iccid - .compile(); - - private static final Pattern PATTERN = new PatternBuilder() - .number("(-?d+),") // index - .text("UNITSTAT,") - .number("(dddd)(dd)(dd),") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("d+,") // node id - .number("([NS])(d+).(d+.d+),") // latitude - .number("([EW])(d+).(d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+),") // battery - .number("(-?d+),") // gsm - .number("(x+),") // state - .number("(ddd)") // mcc - .number("(dd),") // mnc - .number("(-?d+),") // altitude - .number("(d+),") // hdop - .number("(x+),") // cell - .number("d+,") // gps fix time - .number("(x+),") // lac - .number("(d+)") // odometer - .compile(); - - private void sendAcknowledgement(Channel channel, SocketAddress remoteAddress, String index) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(index + ",ACK\r", remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.contains("LOGON")) { - - Parser parser = new Parser(PATTERN_LOGON, sentence); - if (!parser.matches()) { - return null; - } - - sendAcknowledgement(channel, remoteAddress, parser.next()); - - String id = parser.next(); - String iccid = parser.next(); - - getDeviceSession(channel, remoteAddress, iccid, id); - - } else if (sentence.contains("UNITSTAT")) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - sendAcknowledgement(channel, remoteAddress, parser.next()); - - position.setTime(parser.nextDateTime()); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - int rssi = parser.nextInt(0); - position.set(Position.KEY_STATUS, parser.nextHexInt(0)); - - int mcc = parser.nextInt(0); - int mnc = parser.nextInt(0); - - position.setAltitude(parser.nextInt(0)); - - position.set(Position.KEY_HDOP, parser.nextInt(0) * 0.1); - - position.setNetwork(new Network(CellTower.from( - mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0), rssi))); - - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/FoxProtocol.java b/src/org/traccar/protocol/FoxProtocol.java deleted file mode 100644 index 9bac773b5..000000000 --- a/src/org/traccar/protocol/FoxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class FoxProtocol extends BaseProtocol { - - public FoxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "</fox>")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new FoxProtocolDecoder(FoxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FoxProtocolDecoder.java b/src/org/traccar/protocol/FoxProtocolDecoder.java deleted file mode 100644 index 449f00022..000000000 --- a/src/org/traccar/protocol/FoxProtocolDecoder.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 FoxProtocolDecoder extends BaseProtocolDecoder { - - public FoxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // status id - .expression("([AV]),") // validity - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .expression("[^,]*,") // cell info - .number("([01]+) ") // input - .number("(d+) ") // power - .number("(d+) ") // temperature - .number("(d+) ") // rpm - .number("(d+) ") // fuel - .number("(d+) ") // adc 1 - .number("(d+) ") // adc 2 - .number("([01]+) ") // output - .number("(d+),") // odometer - .expression("(.+)") // status info - .compile(); - - private String getAttribute(String xml, String key) { - int start = xml.indexOf(key + "=\""); - if (start != -1) { - start += key.length() + 2; - int end = xml.indexOf("\"", start); - if (end != -1) { - return xml.substring(start, end); - } - } - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String xml = (String) msg; - String id = getAttribute(xml, "id"); - String data = getAttribute(xml, "data"); - - if (id != null && data != null) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, data); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_STATUS, parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_INPUT, parser.nextBinInt(0)); - position.set(Position.KEY_POWER, parser.nextDouble(0) * 0.1); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); - position.set(Position.KEY_RPM, parser.nextInt(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 2, parser.nextInt(0)); - position.set(Position.KEY_OUTPUT, parser.nextBinInt(0)); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - - position.set("statusData", parser.next()); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/FreedomProtocol.java b/src/org/traccar/protocol/FreedomProtocol.java deleted file mode 100644 index bc6b92d5f..000000000 --- a/src/org/traccar/protocol/FreedomProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class FreedomProtocol extends BaseProtocol { - - public FreedomProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new FreedomProtocolDecoder(FreedomProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FreedomProtocolDecoder.java b/src/org/traccar/protocol/FreedomProtocolDecoder.java deleted file mode 100644 index 1d2dd3133..000000000 --- a/src/org/traccar/protocol/FreedomProtocolDecoder.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class FreedomProtocolDecoder extends BaseProtocolDecoder { - - public FreedomProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("IMEI,") - .number("(d+),") // imei - .number("(dddd)/(dd)/(dd), ") // date (yyyy/dd/mm) - .number("(dd):(dd):(dd), ") // time (hh:mm:ss) - .expression("([NS]), ") - .number("Lat:(dd)(d+.d+), ") // latitude - .expression("([EW]), ") - .number("Lon:(ddd)(d+.d+), ") // longitude - .text("Spd:").number("(d+.d+)") // speed - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - - position.setSpeed(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/FreematicsProtocol.java b/src/org/traccar/protocol/FreematicsProtocol.java deleted file mode 100644 index 999b075a1..000000000 --- a/src/org/traccar/protocol/FreematicsProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class FreematicsProtocol extends BaseProtocol { - - public FreematicsProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new FreematicsProtocolDecoder(FreematicsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/org/traccar/protocol/FreematicsProtocolDecoder.java deleted file mode 100644 index ba47699c3..000000000 --- a/src/org/traccar/protocol/FreematicsProtocolDecoder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class FreematicsProtocolDecoder extends BaseProtocolDecoder { - - public FreematicsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private Object decodeEvent( - Channel channel, SocketAddress remoteAddress, String sentence) { - - DeviceSession deviceSession = null; - String event = null; - String time = null; - - for (String pair : sentence.split(",")) { - String[] data = pair.split("="); - String key = data[0]; - String value = data[1]; - switch (key) { - case "ID": - case "VIN": - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress, value); - } - break; - case "EV": - event = value; - break; - case "TS": - time = value; - break; - default: - break; - } - } - - if (channel != null && deviceSession != null && event != null && time != null) { - String message = String.format("1#EV=%s,RX=1,TS=%s", event, time); - message += '*' + Checksum.sum(message); - channel.writeAndFlush(new NetworkMessage(message, remoteAddress)); - } - - return null; - } - - private Object decodePosition( - Channel channel, SocketAddress remoteAddress, String sentence) throws Exception { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - Position position = null; - DateBuilder dateBuilder = null; - - for (String pair : sentence.split(",")) { - String[] data = pair.split("[=:]"); - int key = Integer.parseInt(data[0], 16); - String value = data[1]; - switch (key) { - case 0x0: - if (position != null) { - position.setTime(dateBuilder.getDate()); - positions.add(position); - } - position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - dateBuilder = new DateBuilder(new Date()); - break; - 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(Double.parseDouble(value)); - break; - case 0xD: - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); - break; - case 0xE: - position.setCourse(Integer.parseInt(value)); - break; - case 0xF: - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case 0x20: - position.set(Position.KEY_ACCELERATION, value); - break; - case 0x24: - position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.01); - break; - case 0x81: - position.set(Position.KEY_RSSI, Integer.parseInt(value)); - break; - case 0x82: - position.set(Position.KEY_DEVICE_TEMP, Integer.parseInt(value) * 0.1); - break; - default: - position.set(data[0], value); - break; - } - } - - if (position != null) { - position.setTime(dateBuilder.getDate()); - positions.add(position); - } - - return positions; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - int startIndex = sentence.indexOf('#'); - int endIndex = sentence.indexOf('*'); - - if (startIndex > 0 && endIndex > 0) { - sentence = sentence.substring(startIndex + 1, endIndex); - - if (sentence.startsWith("EV")) { - return decodeEvent(channel, remoteAddress, sentence); - } else { - return decodePosition(channel, remoteAddress, sentence); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/GalileoFrameDecoder.java b/src/org/traccar/protocol/GalileoFrameDecoder.java deleted file mode 100644 index c23d26c83..000000000 --- a/src/org/traccar/protocol/GalileoFrameDecoder.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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 GalileoFrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_MINIMUM_LENGTH = 5; - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - int length = buf.getUnsignedShortLE(buf.readerIndex() + 1) & 0x7fff; - if (buf.readableBytes() >= (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 deleted file mode 100644 index 9b7fe1a4b..000000000 --- a/src/org/traccar/protocol/GalileoProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class GalileoProtocol extends BaseProtocol { - - public GalileoProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new GalileoFrameDecoder()); - pipeline.addLast(new GalileoProtocolEncoder()); - pipeline.addLast(new GalileoProtocolDecoder(GalileoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GalileoProtocolDecoder.java b/src/org/traccar/protocol/GalileoProtocolDecoder.java deleted file mode 100644 index 01c55a9ae..000000000 --- a/src/org/traccar/protocol/GalileoProtocolDecoder.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * 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. - * 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.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -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.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class GalileoProtocolDecoder extends BaseProtocolDecoder { - - public GalileoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private ByteBuf photo; - - private static final Map<Integer, Integer> TAG_LENGTH_MAP = new HashMap<>(); - - static { - int[] l1 = { - 0x01, 0x02, 0x35, 0x43, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd5, 0x88, 0x8a, 0x8b, 0x8c, - 0xa0, 0xaf, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, - 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae - }; - int[] l2 = { - 0x04, 0x10, 0x34, 0x40, 0x41, 0x42, 0x45, 0x46, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60, 0x61, - 0x62, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xd6, 0xd7, 0xd8, 0xd9, 0xda - }; - int[] l3 = { - 0x63, 0x64, 0x6f, 0x5d, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e - }; - int[] l4 = { - 0x20, 0x33, 0x44, 0x90, 0xc0, 0xc2, 0xc3, 0xd3, - 0xd4, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xf0, 0xf9, - 0x5a, 0x47, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, - 0xf7, 0xf8, 0xe2, 0xe9 - }; - for (int i : l1) { - TAG_LENGTH_MAP.put(i, 1); - } - for (int i : l2) { - TAG_LENGTH_MAP.put(i, 2); - } - for (int i : l3) { - TAG_LENGTH_MAP.put(i, 3); - } - for (int i : l4) { - TAG_LENGTH_MAP.put(i, 4); - } - TAG_LENGTH_MAP.put(0x5b, 7); // variable length - TAG_LENGTH_MAP.put(0x5c, 68); - } - - private static int getTagLength(int tag) { - Integer length = TAG_LENGTH_MAP.get(tag); - if (length == null) { - throw new IllegalArgumentException("Unknown tag: " + tag); - } - return length; - } - - private void sendReply(Channel channel, int header, int checksum) { - if (channel != null) { - ByteBuf reply = Unpooled.buffer(3); - reply.writeByte(header); - reply.writeShortLE((short) checksum); - channel.writeAndFlush(new NetworkMessage(reply, channel.remoteAddress())); - } - } - - private void decodeTag(Position position, ByteBuf buf, int tag) { - if (tag >= 0x50 && tag <= 0x57) { - position.set(Position.PREFIX_ADC + (tag - 0x50), buf.readUnsignedShortLE()); - } else if (tag >= 0x60 && tag <= 0x62) { - position.set("fuel" + (tag - 0x60), buf.readUnsignedShortLE()); - } else if (tag >= 0xa0 && tag <= 0xaf) { - position.set("can8BitR" + (tag - 0xa0 + 15), buf.readUnsignedByte()); - } else if (tag >= 0xb0 && tag <= 0xb9) { - position.set("can16BitR" + (tag - 0xb0 + 5), buf.readUnsignedShortLE()); - } else if (tag >= 0xc4 && tag <= 0xd2) { - position.set("can8BitR" + (tag - 0xc4), buf.readUnsignedByte()); - } else if (tag >= 0xd6 && tag <= 0xda) { - position.set("can16BitR" + (tag - 0xd6), buf.readUnsignedShortLE()); - } else if (tag >= 0xdb && tag <= 0xdf) { - position.set("can32BitR" + (tag - 0xdb), buf.readUnsignedIntLE()); - } else if (tag >= 0xe2 && tag <= 0xe9) { - position.set("userData" + (tag - 0xe2), buf.readUnsignedIntLE()); - } else if (tag >= 0xf0 && tag <= 0xf9) { - position.set("can32BitR" + (tag - 0xf0 + 5), buf.readUnsignedIntLE()); - } else { - decodeTagOther(position, buf, tag); - } - } - - private void decodeTagOther(Position position, ByteBuf buf, int tag) { - switch (tag) { - case 0x01: - position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); - break; - case 0x02: - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - break; - case 0x04: - position.set("deviceId", buf.readUnsignedShortLE()); - break; - case 0x10: - position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); - break; - case 0x20: - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - break; - case 0x33: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); - position.setCourse(buf.readUnsignedShortLE() * 0.1); - break; - case 0x34: - position.setAltitude(buf.readShortLE()); - break; - case 0x35: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x40: - position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); - break; - case 0x41: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() / 1000.0); - break; - case 0x42: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() / 1000.0); - break; - case 0x43: - position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - break; - case 0x44: - position.set(Position.KEY_ACCELERATION, buf.readUnsignedIntLE()); - break; - case 0x45: - position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); - break; - case 0x46: - position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); - break; - case 0x48: - position.set("statusExtended", buf.readUnsignedShortLE()); - break; - case 0x58: - position.set("rs2320", buf.readUnsignedShortLE()); - break; - case 0x59: - position.set("rs2321", buf.readUnsignedShortLE()); - break; - case 0x90: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); - break; - case 0xc0: - 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.readUnsignedShortLE() * 0.125); - break; - case 0xc2: - position.set("canB0", buf.readUnsignedIntLE()); - break; - case 0xc3: - position.set("canB1", buf.readUnsignedIntLE()); - break; - case 0xd4: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0xe0: - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - break; - case 0xe1: - position.set(Position.KEY_RESULT, - buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); - break; - case 0xea: - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); - break; - default: - buf.skipBytes(getTagLength(tag)); - break; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int header = buf.readUnsignedByte(); - if (header == 0x01) { - return decodePositions(channel, remoteAddress, buf); - } else if (header == 0x07) { - return decodePhoto(channel, remoteAddress, buf); - } - - return null; - } - - private Object decodePositions( - Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { - - int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; - - List<Position> positions = new LinkedList<>(); - Set<Integer> tags = new HashSet<>(); - boolean hasLocation = false; - - DeviceSession deviceSession = null; - Position position = new Position(getProtocolName()); - - while (buf.readerIndex() < length) { - - int tag = buf.readUnsignedByte(); - if (tags.contains(tag)) { - if (hasLocation && position.getFixTime() != null) { - positions.add(position); - } - tags.clear(); - hasLocation = false; - position = new Position(getProtocolName()); // new position starts - } - tags.add(tag); - - if (tag == 0x03) { - deviceSession = getDeviceSession( - channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); - } else if (tag == 0x30) { - hasLocation = true; - position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00); - position.setLatitude(buf.readIntLE() / 1000000.0); - position.setLongitude(buf.readIntLE() / 1000000.0); - } else { - decodeTag(position, buf, tag); - } - - } - - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - } - - if (hasLocation && position.getFixTime() != null) { - positions.add(position); - } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) { - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, null); - positions.add(position); - } - - sendReply(channel, 0x02, buf.readUnsignedShortLE()); - - for (Position p : positions) { - p.setDeviceId(deviceSession.getDeviceId()); - } - - return positions.isEmpty() ? null : positions; - } - - private Object decodePhoto( - Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { - - int length = buf.readUnsignedShortLE(); - - Position position = null; - - if (length > 1) { - - if (photo == null) { - photo = Unpooled.buffer(); - } - - buf.readUnsignedByte(); // part number - photo.writeBytes(buf, length - 1); - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); - - 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; - - } - - sendReply(channel, 0x07, buf.readUnsignedShortLE()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/GalileoProtocolEncoder.java b/src/org/traccar/protocol/GalileoProtocolEncoder.java deleted file mode 100644 index 3b2145e74..000000000 --- a/src/org/traccar/protocol/GalileoProtocolEncoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class GalileoProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeText(String uniqueId, String text) { - - ByteBuf buf = Unpooled.buffer(256); - - buf.writeByte(0x01); - 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.writeShortLE(0); // not needed if imei provided - - buf.writeByte(0xE0); // index tag - buf.writeIntLE(0); // index - - buf.writeByte(0xE1); // command text tag - buf.writeByte(text.length()); - buf.writeBytes(text.getBytes(StandardCharsets.US_ASCII)); - - buf.writeShortLE(Checksum.crc16(Checksum.CRC16_MODBUS, buf.nioBuffer(0, buf.writerIndex()))); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeText(getUniqueId(command.getDeviceId()), command.getString(Command.KEY_DATA)); - case Command.TYPE_OUTPUT_CONTROL: - return encodeText(getUniqueId(command.getDeviceId()), - "Out " + command.getInteger(Command.KEY_INDEX) + "," + command.getString(Command.KEY_DATA)); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/GatorProtocol.java b/src/org/traccar/protocol/GatorProtocol.java deleted file mode 100644 index ca81caefb..000000000 --- a/src/org/traccar/protocol/GatorProtocol.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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; - -public class GatorProtocol extends BaseProtocol { - - public GatorProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); - pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GatorProtocolDecoder.java b/src/org/traccar/protocol/GatorProtocolDecoder.java deleted file mode 100644 index 31500bae6..000000000 --- a/src/org/traccar/protocol/GatorProtocolDecoder.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class GatorProtocolDecoder extends BaseProtocolDecoder { - - public GatorProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_HEARTBEAT = 0x21; - public static final int MSG_POSITION_DATA = 0x80; - public static final int MSG_ROLLCALL_RESPONSE = 0x81; - public static final int MSG_ALARM_DATA = 0x82; - public static final int MSG_TERMINAL_STATUS = 0x83; - public static final int MSG_MESSAGE = 0x84; - public static final int MSG_TERMINAL_ANSWER = 0x85; - public static final int MSG_BLIND_AREA = 0x8E; - public static final int MSG_PICTURE_FRAME = 0x54; - public static final int MSG_CAMERA_RESPONSE = 0x56; - public static final int MSG_PICTURE_DATA = 0x57; - - public static String decodeId(int b1, int b2, int b3, int b4) { - - int d1 = 30 + ((b1 >> 7) << 3) + ((b2 >> 7) << 2) + ((b3 >> 7) << 1) + (b4 >> 7); - int d2 = b1 & 0x7f; - int d3 = b2 & 0x7f; - int d4 = b3 & 0x7f; - int d5 = b4 & 0x7f; - - return String.format("%02d%02d%02d%02d%02d", d1, d2, d3, d4, d5); - } - - private void sendResponse(Channel channel, SocketAddress remoteAddress, byte calibration) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(0x24); response.writeByte(0x24); // header - response.writeByte(MSG_HEARTBEAT); // size - response.writeShort(5); - response.writeByte(calibration); - response.writeByte(0); // main order - response.writeByte(0); // slave order - response.writeByte(1); // calibration - response.writeByte(0x0D); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - int type = buf.readUnsignedByte(); - buf.readUnsignedShort(); // length - - String id = decodeId( - buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte()); - - 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) { - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "1" + id, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - position.setLatitude(BcdUtil.readCoordinate(buf)); - position.setLongitude(BcdUtil.readCoordinate(buf)); - position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4))); - position.setCourse(BcdUtil.readInteger(buf, 4)); - - int flags = buf.readUnsignedByte(); - position.setValid((flags & 0x80) != 0); - position.set(Position.KEY_SATELLITES, flags & 0x0f); - - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - position.set("key", buf.readUnsignedByte()); - position.set("oil", buf.readUnsignedShort() / 10.0); - position.set(Position.KEY_POWER, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/GenxProtocol.java b/src/org/traccar/protocol/GenxProtocol.java deleted file mode 100644 index c87ba946a..000000000 --- a/src/org/traccar/protocol/GenxProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class GenxProtocol extends BaseProtocol { - - public GenxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new GenxProtocolDecoder(GenxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java deleted file mode 100644 index 2ae9de7a0..000000000 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.text.SimpleDateFormat; - -public class GenxProtocolDecoder extends BaseProtocolDecoder { - - private int[] reportColumns; - - public GenxProtocolDecoder(Protocol protocol) { - super(protocol); - setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); - } - - public void setReportColumns(String format) { - String[] columns = format.split(","); - reportColumns = new int[columns.length]; - for (int i = 0; i < columns.length; i++) { - reportColumns[i] = Integer.parseInt(columns[i]); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String[] values = ((String) msg).split(","); - - Position position = new Position(getProtocolName()); - position.setValid(true); - - for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) { - switch (reportColumns[i]) { - case 1: - case 28: - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); - if (deviceSession != null) { - position.setDeviceId(deviceSession.getDeviceId()); - } - break; - case 2: - position.setTime(new SimpleDateFormat("MM/dd/yy HH:mm:ss").parse(values[i])); - break; - case 3: - position.setLatitude(Double.parseDouble(values[i])); - break; - case 4: - position.setLongitude(Double.parseDouble(values[i])); - break; - case 11: - position.set(Position.KEY_IGNITION, values[i].equals("ON")); - break; - case 13: - position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[i]))); - break; - case 17: - position.setCourse(Integer.parseInt(values[i])); - break; - case 23: - position.set(Position.KEY_ODOMETER, Double.parseDouble(values[i]) * 1000); - break; - case 27: - position.setAltitude(UnitsConverter.metersFromFeet(Integer.parseInt(values[i]))); - break; - case 46: - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - default: - break; - } - } - - return position.getDeviceId() != 0 ? position : null; - } - -} diff --git a/src/org/traccar/protocol/Gl100Protocol.java b/src/org/traccar/protocol/Gl100Protocol.java deleted file mode 100644 index 063e606db..000000000 --- a/src/org/traccar/protocol/Gl100Protocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -public class Gl100Protocol extends BaseProtocol { - - public Gl100Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/org/traccar/protocol/Gl100ProtocolDecoder.java deleted file mode 100644 index ae0383e5c..000000000 --- a/src/org/traccar/protocol/Gl100ProtocolDecoder.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class Gl100ProtocolDecoder extends BaseProtocolDecoder { - - public Gl100ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("+RESP:") - .expression("GT...,") - .number("(d{15}),") // imei - .groupBegin() - .number("d+,") // number - .number("d,") // reserved / geofence id - .number("d+") // reserved / geofence alert // battery - .or() - .number("[^,]*") // calling number - .groupEnd(",") - .expression("([01]),") // gps fix - .number("(d+.d),") // speed - .number("(d+),") // course - .number("(-?d+.d),") // altitude - .number("d*,") // gps accuracy - .number("(-?d+.d+),") // longitude - .number("(-?d+.d+),") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.contains("AT+GTHBD=") && channel != null) { - String response = "+RESP:GTHBD,GPRS ACTIVE,"; - response += sentence.substring(9, sentence.lastIndexOf(',')); - response += '\0'; - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); // heartbeat response - } - - 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.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.nextInt(0) == 0); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - - position.setTime(parser.nextDateTime()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java deleted file mode 100644 index c3339bea5..000000000 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitBuffer; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -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; -import java.util.LinkedList; -import java.util.List; - -public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { - - public Gl200BinaryProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private Date decodeTime(ByteBuf buf) { - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - return dateBuilder.getDate(); - } - - public static final int MSG_RSP_LCB = 3; - public static final int MSG_RSP_GEO = 8; - public static final int MSG_RSP_COMPRESSED = 100; - - private List<Position> decodeLocation(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - List<Position> positions = new LinkedList<>(); - - int type = buf.readUnsignedByte(); - - buf.readUnsignedInt(); // mask - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version - buf.readUnsignedShort(); // firmware version - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - - int battery = buf.readUnsignedByte(); - int power = buf.readUnsignedShort(); - - if (type == MSG_RSP_GEO) { - buf.readUnsignedByte(); // reserved - buf.readUnsignedByte(); // reserved - } - - buf.readUnsignedByte(); // motion status - int satellites = buf.readUnsignedByte(); - - if (type != MSG_RSP_COMPRESSED) { - buf.readUnsignedByte(); // index - } - - if (type == MSG_RSP_LCB) { - buf.readUnsignedByte(); // phone length - for (int b = buf.readUnsignedByte();; b = buf.readUnsignedByte()) { - if ((b & 0xf) == 0xf || (b & 0xf0) == 0xf0) { - break; - } - } - } - - if (type == MSG_RSP_COMPRESSED) { - - int count = buf.readUnsignedShort(); - - BitBuffer bits; - int speed = 0; - int heading = 0; - int latitude = 0; - int longitude = 0; - long time = 0; - - for (int i = 0; i < count; i++) { - - if (time > 0) { - time += 1; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - switch (BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 8 - 2)) { - case 1: - bits = new BitBuffer(buf.readSlice(3)); - bits.readUnsigned(2); // point attribute - bits.readUnsigned(1); // fix type - speed = bits.readUnsigned(12); - heading = bits.readUnsigned(9); - longitude = buf.readInt(); - latitude = buf.readInt(); - if (time == 0) { - time = buf.readUnsignedInt(); - } - break; - case 2: - bits = new BitBuffer(buf.readSlice(5)); - bits.readUnsigned(2); // point attribute - bits.readUnsigned(1); // fix type - speed += bits.readSigned(7); - heading += bits.readSigned(7); - longitude += bits.readSigned(12); - latitude += bits.readSigned(11); - break; - default: - buf.readUnsignedByte(); // invalid or same - continue; - } - - position.setValid(true); - position.setTime(new Date(time * 1000)); - position.setSpeed(UnitsConverter.knotsFromKph(speed * 0.1)); - position.setCourse(heading); - position.setLongitude(longitude * 0.000001); - position.setLatitude(latitude * 0.000001); - - positions.add(position); - - } - - } else { - - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_BATTERY_LEVEL, battery); - position.set(Position.KEY_POWER, power); - position.set(Position.KEY_SATELLITES, satellites); - - int hdop = buf.readUnsignedByte(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readShort()); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); - - position.setTime(decodeTime(buf)); - - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort()))); - - buf.readUnsignedByte(); // reserved - - positions.add(position); - - } - - } - - return positions; - } - - public static final int MSG_EVT_BPL = 6; - public static final int MSG_EVT_VGN = 45; - public static final int MSG_EVT_VGF = 46; - public static final int MSG_EVT_UPD = 15; - public static final int MSG_EVT_IDF = 17; - public static final int MSG_EVT_GSS = 21; - public static final int MSG_EVT_GES = 26; - public static final int MSG_EVT_GPJ = 31; - public static final int MSG_EVT_RMD = 35; - public static final int MSG_EVT_JDS = 33; - public static final int MSG_EVT_CRA = 23; - public static final int MSG_EVT_UPC = 34; - - private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - - int type = buf.readUnsignedByte(); - - buf.readUnsignedInt(); // mask - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version - - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); - - buf.readUnsignedByte(); // motion status - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - switch (type) { - case MSG_EVT_BPL: - buf.readUnsignedShort(); // backup battery voltage - break; - case MSG_EVT_VGN: - case MSG_EVT_VGF: - buf.readUnsignedShort(); // reserved - buf.readUnsignedByte(); // report type - buf.readUnsignedInt(); // ignition duration - break; - case MSG_EVT_UPD: - buf.readUnsignedShort(); // code - buf.readUnsignedByte(); // retry - break; - case MSG_EVT_IDF: - buf.readUnsignedInt(); // idling duration - break; - case MSG_EVT_GSS: - buf.readUnsignedByte(); // gps signal status - buf.readUnsignedInt(); // reserved - break; - case MSG_EVT_GES: - buf.readUnsignedShort(); // trigger geo id - buf.readUnsignedByte(); // trigger geo enable - buf.readUnsignedByte(); // trigger mode - buf.readUnsignedInt(); // radius - buf.readUnsignedInt(); // check interval - break; - case MSG_EVT_GPJ: - buf.readUnsignedByte(); // cw jamming value - buf.readUnsignedByte(); // gps jamming state - break; - case MSG_EVT_RMD: - buf.readUnsignedByte(); // roaming state - break; - case MSG_EVT_JDS: - buf.readUnsignedByte(); // jamming state - break; - case MSG_EVT_CRA: - buf.readUnsignedByte(); // crash counter - break; - case MSG_EVT_UPC: - buf.readUnsignedByte(); // command id - buf.readUnsignedShort(); // result - break; - default: - break; - } - - buf.readUnsignedByte(); // count - - int hdop = buf.readUnsignedByte(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readShort()); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); - - position.setTime(decodeTime(buf)); - - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort()))); - - buf.readUnsignedByte(); // reserved - - return position; - } - - public static final int MSG_INF_GPS = 2; - public static final int MSG_INF_CID = 4; - public static final int MSG_INF_CSQ = 5; - public static final int MSG_INF_VER = 6; - public static final int MSG_INF_BAT = 7; - public static final int MSG_INF_TMZ = 9; - public static final int MSG_INF_GIR = 10; - - private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - - int type = buf.readUnsignedByte(); - - buf.readUnsignedInt(); // mask - buf.readUnsignedShort(); // length - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version - - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - - if (type == MSG_INF_VER) { - buf.readUnsignedShort(); // hardware version - buf.readUnsignedShort(); // mcu version - buf.readUnsignedShort(); // reserved - } - - buf.readUnsignedByte(); // motion status - buf.readUnsignedByte(); // reserved - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // mode - buf.skipBytes(7); // last fix time - buf.readUnsignedByte(); // reserved - buf.readUnsignedByte(); - buf.readUnsignedShort(); // response report mask - buf.readUnsignedShort(); // ign interval - buf.readUnsignedShort(); // igf interval - buf.readUnsignedInt(); // reserved - buf.readUnsignedByte(); // reserved - - if (type == MSG_INF_BAT) { - position.set(Position.KEY_CHARGE, buf.readUnsignedByte() != 0); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - } - - buf.skipBytes(10); // iccid - - if (type == MSG_INF_CSQ) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - buf.readUnsignedByte(); - } - - buf.readUnsignedByte(); // time zone flags - buf.readUnsignedShort(); // time zone offset - - if (type == MSG_INF_GIR) { - buf.readUnsignedByte(); // gir trigger - buf.readUnsignedByte(); // cell number - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort()))); - buf.readUnsignedByte(); // ta - buf.readUnsignedByte(); // rx level - } - - getLastLocation(position, decodeTime(buf)); - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - switch (buf.readSlice(4).toString(StandardCharsets.US_ASCII)) { - case "+RSP": - return decodeLocation(channel, remoteAddress, buf); - case "+INF": - return decodeInformation(channel, remoteAddress, buf); - case "+EVT": - return decodeEvent(channel, remoteAddress, buf); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Gl200FrameDecoder.java b/src/org/traccar/protocol/Gl200FrameDecoder.java deleted file mode 100644 index c192cc28d..000000000 --- a/src/org/traccar/protocol/Gl200FrameDecoder.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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. - * 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.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 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(ByteBuf buf) { - String header = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); - if (header.equals("+ACK")) { - return buf.getByte(buf.readerIndex() + header.length()) != (byte) ':'; - } else { - return BINARY_HEADERS.contains(header); - } - } - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < MINIMUM_LENGTH) { - return null; - } - - if (isBinary(buf)) { - - int length; - switch (buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)) { - case "+ACK": - length = buf.getUnsignedByte(buf.readerIndex() + 6); - break; - case "+INF": - case "+BNF": - length = buf.getUnsignedShort(buf.readerIndex() + 7); - break; - case "+HBD": - length = buf.getUnsignedByte(buf.readerIndex() + 5); - break; - case "+CRD": - case "+BRD": - length = buf.getUnsignedShort(buf.readerIndex() + 6); - break; - default: - length = buf.getUnsignedShort(buf.readerIndex() + 9); - break; - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - } else { - - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '$'); - if (endIndex < 0) { - endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); - } - if (endIndex > 0) { - ByteBuf frame = buf.readRetainedSlice(endIndex - buf.readerIndex()); - buf.readByte(); // delimiter - return frame; - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java deleted file mode 100644 index c5343dae0..000000000 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -import io.netty.handler.codec.string.StringEncoder; - -public class Gl200Protocol extends BaseProtocol { - - public Gl200Protocol() { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_IDENTIFICATION, - Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Gl200FrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Gl200ProtocolEncoder()); - pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Gl200ProtocolEncoder()); - pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java deleted file mode 100644 index ca1df7a13..000000000 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - * 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.BaseProtocolDecoder; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import org.traccar.Protocol; - -import java.net.SocketAddress; - -public class Gl200ProtocolDecoder extends BaseProtocolDecoder { - - private final Gl200TextProtocolDecoder textProtocolDecoder; - private final Gl200BinaryProtocolDecoder binaryProtocolDecoder; - - public Gl200ProtocolDecoder(Protocol protocol) { - super(protocol); - textProtocolDecoder = new Gl200TextProtocolDecoder(protocol); - binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (Gl200FrameDecoder.isBinary(buf)) { - return binaryProtocolDecoder.decode(channel, remoteAddress, msg); - } else { - return textProtocolDecoder.decode(channel, remoteAddress, msg); - } - } - -} diff --git a/src/org/traccar/protocol/Gl200ProtocolEncoder.java b/src/org/traccar/protocol/Gl200ProtocolEncoder.java deleted file mode 100644 index 285106c67..000000000 --- a/src/org/traccar/protocol/Gl200ProtocolEncoder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.model.Command; - -public class Gl200ProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, ""); - - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "AT+GTRTO={%s},1,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "AT+GTOUT={%s},1,,,0,0,0,0,0,0,0,,,,,,,FFFF$", - Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "AT+GTOUT={%s},0,,,0,0,0,0,0,0,0,,,,,,,FFFF$", - Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "AT+GTRTO={%s},8,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "AT+GTRTO={%s},3,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java deleted file mode 100644 index aeb57a116..000000000 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ /dev/null @@ -1,1266 +0,0 @@ -/* - * 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.protocol; - -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -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 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; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.LinkedList; -import java.util.List; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { - - private boolean ignoreFixTime; - - public Gl200TextProtocolDecoder(Protocol protocol) { - super(protocol); - - ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime"); - } - - private static final Pattern PATTERN_ACK = new PatternBuilder() - .text("+ACK:GT") - .expression("...,") // type - .number("([0-9A-Z]{2}xxxx),") // protocol version - .number("(d{15}|x{14}),") // imei - .any().text(",") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_INF = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTINF,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17},)?") // vin - .expression("(?:[^,]+)?,") // device name - .number("(xx),") // state - .expression("(?:[0-9Ff]{20})?,") // iccid - .number("(d{1,2}),") // rssi - .number("d{1,2},") - .expression("[01],") // external power - .number("([d.]+)?,") // odometer or external power - .number("d*,") // backup battery or lightness - .number("(d+.d+),") // battery - .expression("([01]),") // charging - .number("(?:d),") // led - .number("(?:d)?,") // gps on need - .number("(?:d)?,") // gps antenna type - .number("(?:d)?,").optional() // gps antenna state - .number("d{14},") // last fix time - .groupBegin() - .number("(d+),") // battery percentage - .number("[d.]*,") // flash type / power - .number("(-?[d.]+)?,,,") // temperature - .or() - .expression("(?:[01])?,").optional() // pin15 mode - .number("(d+)?,") // adc1 - .number("(d+)?,").optional() // adc2 - .number("(xx)?,") // digital input - .number("(xx)?,") // digital output - .number("[-+]dddd,") // timezone - .expression("[01],") // daylight saving - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_VER = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTVER,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .expression("([^,]*),") // device type - .number("(xxxx),") // firmware version - .number("(xxxx),") // hardware version - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+)?,") // mcc - .number("(d+)?,") // mnc - .groupBegin() - .number("(d+),") // lac - .number("(d+),") // cid - .or() - .number("(x+)?,") // lac - .number("(x+)?,") // cid - .groupEnd() - .number("(?:d+|(d+.d))?,") // odometer - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .text("+RESP:GTOBD,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17})?,") // vin - .expression("[^,]{0,20},") // device name - .expression("[01],") // report type - .number("x{1,8},") // report mask - .expression("(?:[0-9A-Z]{17})?,") // vin - .number("[01],") // obd connect - .number("(?:d{1,5})?,") // obd voltage - .number("(?:x{8})?,") // support pids - .number("(d{1,5})?,") // engine rpm - .number("(d{1,3})?,") // speed - .number("(-?d{1,3})?,") // coolant temp - .number("(d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d{1,5})?,") // dtcs cleared distance - .number("(?:d{1,5})?,") - .expression("([01])?,") // obd connect - .number("(d{1,3})?,") // number of dtcs - .number("(x*),") // dtcs - .number("(d{1,3})?,") // throttle - .number("(?:d{1,3})?,") // engine load - .number("(d{1,3})?,") // fuel level - .expression("(?:[0-9A],)?") // obd protocol - .number("(d+),") // odometer - .expression(PATTERN_LOCATION.pattern()) - .number("(d{1,7}.d)?,") // odometer - .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_FRI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:([0-9A-Z]{17}),)?") // vin - .expression("[^,]*,") // device name - .number("(d+)?,") // power - .number("d{1,2},").optional() // report type - .number("d{1,2},").optional() // count - .number(",").optional() // reserved - .number("(d+),").optional() // battery - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .groupBegin() - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .number("(d+)?,") // rpm - .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d+)?,") // fuel level - .or() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .groupEnd() - .any() - .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_ERI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTERI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(x{8}),") // mask - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,").optional() // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .expression("(.*)") // additional data - .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_IGN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTIG[NF],") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d+,") // ignition off duration - .expression(PATTERN_LOCATION.pattern()) - .number("(d{5}:dd:dd)?,") // hour meter - .number("(d{1,7}.d)?,") // odometer - .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_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 - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,,") // device name - .number("([^,]+),") // rfid - .expression("[01],") // report type - .number("1,") // count - .expression(PATTERN_LOCATION.pattern()) - .number("(d+.d),") // odometer - .text(",,,,") - .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_WIF = new PatternBuilder() - .text("+RESP:GTWIF,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(d+),") // count - .number("((?:x{12},-?d+,,,,)+),,,,") // wifi - .number("(d{1,3}),") // battery - .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_GSM = new PatternBuilder() - .text("+RESP:GTGSM,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:STR|CTN|NMR|RTL),") // fix type - .expression("(.*)") // cells - .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_PNA = new PatternBuilder() - .text("+RESP:GT").expression("P[NF]A,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .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 = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d*,") - .number("(x{1,2}),") // report type - .number("d{1,2},") // count - .expression(PATTERN_LOCATION.pattern()) - .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_BASIC = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version - .number("(d{15}|x{14}),") // imei - .any() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),").optional(4) // cell - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_ACK, sentence); - if (parser.matches()) { - String protocolVersion = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - if (type.equals("HBD")) { - if (channel != null) { - parser.skip(6); - channel.writeAndFlush(new NetworkMessage( - "+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress)); - } - } else { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, parser.nextDateTime()); - position.setValid(false); - position.set(Position.KEY_RESULT, "Command " + type + " accepted"); - return position; - } - } - return null; - } - - private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) { - if (parser.matches()) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession != null) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - return position; - } - } - return null; - } - - private void decodeDeviceTime(Position position, Parser parser) { - if (parser.hasNext(6)) { - if (ignoreFixTime) { - position.setTime(parser.nextDateTime()); - } else { - position.setDeviceTime(parser.nextDateTime()); - } - } - } - - 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); - if (position == null) { - return null; - } - - switch (parser.nextHexInt()) { - case 0x16: - case 0x1A: - case 0x12: - position.set(Position.KEY_IGNITION, false); - position.set(Position.KEY_MOTION, true); - break; - case 0x11: - position.set(Position.KEY_IGNITION, false); - position.set(Position.KEY_MOTION, false); - break; - case 0x21: - position.set(Position.KEY_IGNITION, true); - position.set(Position.KEY_MOTION, false); - break; - case 0x22: - position.set(Position.KEY_IGNITION, true); - position.set(Position.KEY_MOTION, true); - break; - case 0x41: - position.set(Position.KEY_MOTION, false); - break; - case 0x42: - position.set(Position.KEY_MOTION, true); - break; - default: - break; - } - - position.set(Position.KEY_RSSI, parser.nextInt()); - - parser.next(); // odometer or external power - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_CHARGE, parser.nextInt() == 1); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - - getLastLocation(position, parser.nextDateTime()); - - position.set(Position.KEY_INDEX, parser.nextHexInt()); - - return position; - } - - private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_VER, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set("deviceType", parser.next()); - position.set(Position.KEY_VERSION_FW, parser.nextHexInt()); - position.set(Position.KEY_VERSION_HW, parser.nextHexInt()); - - getLastLocation(position, parser.nextDateTime()); - - return position; - } - - private void skipLocation(Parser parser) { - parser.skip(19); - } - - private void decodeLocation(Position position, Parser parser) { - Integer hdop = parser.nextInt(); - position.setValid(hdop == null || hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(8)) { - position.setValid(true); - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); - position.setTime(parser.nextDateTime()); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(), parser.nextInt()))); - } - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt()))); - } - } - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - } - } - - private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_OBD, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_OBD_SPEED, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); - position.set("dtcsClearedDistance", parser.nextInt()); - if (parser.hasNext()) { - position.set("odbConnect", parser.nextInt() == 1); - } - position.set("dtcsNumber", parser.nextInt()); - position.set("dtcsCodes", parser.next()); - position.set(Position.KEY_THROTTLE, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - if (parser.hasNext()) { - position.set(Position.KEY_OBD_ODOMETER, parser.nextInt() * 1000); - } - - decodeLocation(position, parser); - - if (parser.hasNext()) { - position.set(Position.KEY_OBD_ODOMETER, (int) (parser.nextDouble() * 1000)); - } - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeCan(Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException { - Position position = new Position(getProtocolName()); - - int index = 0; - String[] values = sentence.split(","); - - index += 1; // header - index += 1; // protocol version - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - position.setDeviceId(deviceSession.getDeviceId()); - - index += 1; // device name - index += 1; // report type - index += 1; // canbus state - long reportMask = Long.parseLong(values[index++], 16); - long reportMaskExt = 0; - - if (BitUtil.check(reportMask, 0)) { - position.set(Position.KEY_VIN, values[index++]); - } - if (BitUtil.check(reportMask, 1)) { - position.set(Position.KEY_IGNITION, Integer.parseInt(values[index++]) > 0); - } - if (BitUtil.check(reportMask, 2)) { - position.set(Position.KEY_OBD_ODOMETER, values[index++]); - } - if (BitUtil.check(reportMask, 3) && !values[index++].isEmpty()) { - position.set(Position.KEY_FUEL_USED, Double.parseDouble(values[index - 1])); - } - if (BitUtil.check(reportMask, 5) && !values[index++].isEmpty()) { - position.set(Position.KEY_RPM, Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 4) && !values[index++].isEmpty()) { - position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1]))); - } - if (BitUtil.check(reportMask, 6) && !values[index++].isEmpty()) { - position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 7) && !values[index++].isEmpty()) { - position.set(Position.KEY_FUEL_CONSUMPTION, Double.parseDouble(values[index - 1].substring(1))); - } - if (BitUtil.check(reportMask, 8) && !values[index++].isEmpty()) { - position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(values[index - 1].substring(1))); - } - if (BitUtil.check(reportMask, 9) && !values[index++].isEmpty()) { - position.set("range", Long.parseLong(values[index - 1]) * 100); - } - if (BitUtil.check(reportMask, 10) && !values[index++].isEmpty()) { - position.set(Position.KEY_THROTTLE, Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 11) && !values[index++].isEmpty()) { - position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Double.parseDouble(values[index - 1]))); - } - if (BitUtil.check(reportMask, 12)) { - position.set("drivingHours", Double.parseDouble(values[index++])); - } - if (BitUtil.check(reportMask, 13)) { - position.set("idleHours", Double.parseDouble(values[index++])); - } - if (BitUtil.check(reportMask, 14) && !values[index++].isEmpty()) { - position.set("idleFuelConsumption", Double.parseDouble(values[index - 1])); - } - if (BitUtil.check(reportMask, 15) && !values[index++].isEmpty()) { - position.set(Position.KEY_AXLE_WEIGHT, Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 16) && !values[index++].isEmpty()) { - position.set("tachographInfo", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 17) && !values[index++].isEmpty()) { - position.set("indicators", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 18) && !values[index++].isEmpty()) { - position.set("lights", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 19) && !values[index++].isEmpty()) { - position.set("doors", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMask, 20) && !values[index++].isEmpty()) { - position.set("vehicleOverspeed", Double.parseDouble(values[index - 1])); - } - if (BitUtil.check(reportMask, 21) && !values[index++].isEmpty()) { - position.set("engineOverspeed", Double.parseDouble(values[index - 1])); - } - if (BitUtil.check(reportMask, 29)) { - reportMaskExt = Long.parseLong(values[index++], 16); - } - if (BitUtil.check(reportMaskExt, 0) && !values[index++].isEmpty()) { - position.set("adBlueLevel", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMaskExt, 1) && !values[index++].isEmpty()) { - position.set("axleWeight1", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMaskExt, 2) && !values[index++].isEmpty()) { - position.set("axleWeight3", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMaskExt, 3) && !values[index++].isEmpty()) { - position.set("axleWeight4", Integer.parseInt(values[index - 1])); - } - if (BitUtil.check(reportMaskExt, 4)) { - index += 1; // tachograph overspeed - } - if (BitUtil.check(reportMaskExt, 5)) { - index += 1; // tachograph motion - } - if (BitUtil.check(reportMaskExt, 6)) { - index += 1; // tachograph direction - } - if (BitUtil.check(reportMaskExt, 7) && !values[index++].isEmpty()) { - position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[index - 1]) * 0.001); - } - if (BitUtil.check(reportMaskExt, 8)) { - index += 1; // pedal breaking factor - } - if (BitUtil.check(reportMaskExt, 9)) { - index += 1; // engine breaking factor - } - if (BitUtil.check(reportMaskExt, 10)) { - index += 1; // total accelerator kick-downs - } - if (BitUtil.check(reportMaskExt, 11)) { - index += 1; // total effective engine speed - } - if (BitUtil.check(reportMaskExt, 12)) { - index += 1; // total cruise control time - } - if (BitUtil.check(reportMaskExt, 13)) { - index += 1; // total accelerator kick-down time - } - if (BitUtil.check(reportMaskExt, 14)) { - index += 1; // total brake application - } - if (BitUtil.check(reportMaskExt, 15) && !values[index++].isEmpty()) { - position.set("driver1Card", values[index - 1]); - } - if (BitUtil.check(reportMaskExt, 16) && !values[index++].isEmpty()) { - position.set("driver2Card", values[index - 1]); - } - if (BitUtil.check(reportMaskExt, 17) && !values[index++].isEmpty()) { - position.set("driver1Name", values[index - 1]); - } - if (BitUtil.check(reportMaskExt, 18) && !values[index++].isEmpty()) { - position.set("driver2Name", values[index - 1]); - } - if (BitUtil.check(reportMaskExt, 19) && !values[index++].isEmpty()) { - position.set("registration", values[index - 1]); - } - if (BitUtil.check(reportMaskExt, 20)) { - index += 1; // expansion information - } - if (BitUtil.check(reportMaskExt, 21)) { - index += 1; // rapid brakings - } - if (BitUtil.check(reportMaskExt, 22)) { - index += 1; // rapid accelerations - } - if (BitUtil.check(reportMaskExt, 23)) { - index += 1; // engine torque - } - - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - - if (BitUtil.check(reportMask, 30)) { - while (values[index].isEmpty()) { - index += 1; - } - position.setValid(Integer.parseInt(values[index++]) > 0); - if (!values[index].isEmpty()) { - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - position.setCourse(Integer.parseInt(values[index++])); - position.setAltitude(Double.parseDouble(values[index++])); - position.setLongitude(Double.parseDouble(values[index++])); - position.setLatitude(Double.parseDouble(values[index++])); - position.setTime(dateFormat.parse(values[index++])); - } else { - index += 6; // no location - getLastLocation(position, null); - } - } else { - getLastLocation(position, null); - } - - if (BitUtil.check(reportMask, 31)) { - index += 4; // cell - index += 1; // reserved - } - - if (ignoreFixTime) { - position.setTime(dateFormat.parse(values[index])); - } else { - position.setDeviceTime(dateFormat.parse(values[index])); - } - - return position; - } - - private void decodeStatus(Position position, Parser parser) { - if (parser.hasNext(3)) { - int ignition = parser.nextHexInt(); - if (BitUtil.check(ignition, 4)) { - position.set(Position.KEY_IGNITION, false); - } else if (BitUtil.check(ignition, 5)) { - position.set(Position.KEY_IGNITION, true); - } - position.set(Position.KEY_INPUT, parser.nextHexInt()); - position.set(Position.KEY_OUTPUT, parser.nextHexInt()); - } - } - - private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_FRI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - LinkedList<Position> positions = new LinkedList<>(); - - String vin = parser.next(); - Integer power = parser.nextInt(); - Integer battery = parser.nextInt(); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VIN, vin); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - skipLocation(parser); - - if (power != null && power > 10) { - position.set(Position.KEY_POWER, power * 0.001); // only on some devices - } - if (battery != null) { - position.set(Position.KEY_BATTERY_LEVEL, battery); - } - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - } - 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()); - - decodeStatus(position, parser); - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - } - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - decodeDeviceTime(position, parser); - if (ignoreFixTime) { - positions.clear(); - positions.add(position); - } - - return positions; - } - - private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_ERI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - long mask = parser.nextHexLong(); - - LinkedList<Position> positions = new LinkedList<>(); - - Integer power = parser.nextInt(); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - skipLocation(parser); - - if (power != null) { - position.set(Position.KEY_POWER, power * 0.001); - } - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - 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()); - - decodeStatus(position, parser); - - int index = 0; - String[] data = parser.next().split(","); - - index += 1; // device type - - if (BitUtil.check(mask, 0)) { - index += 1; // digital fuel sensor data - } - - if (BitUtil.check(mask, 1)) { - int deviceCount = Integer.parseInt(data[index++]); - for (int i = 1; i <= deviceCount; i++) { - index += 1; // id - index += 1; // type - if (!data[index++].isEmpty()) { - position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index - 1], 16) * 0.0625); - } - } - } - - if (BitUtil.check(mask, 2)) { - index += 1; // can data - } - - if (BitUtil.check(mask, 3) || BitUtil.check(mask, 4)) { - int deviceCount = Integer.parseInt(data[index++]); - for (int i = 1; i <= deviceCount; i++) { - index += 1; // type - if (BitUtil.check(mask, 3)) { - position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(data[index++])); - } - if (BitUtil.check(mask, 4)) { - index += 1; // volume - } - } - } - - decodeDeviceTime(position, parser); - if (ignoreFixTime) { - positions.clear(); - positions.add(position); - } - - return positions; - } - - private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IGN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - decodeLocation(position, parser); - - 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); - - 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); - if (position == null) { - return null; - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_WIF, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - parser.nextInt(); // count - Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); - while (matcher.find()) { - String mac = matcher.group(1).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2)))); - } - - position.setNetwork(network); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - return position; - } - - private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_GSM, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - String[] data = parser.next().split(","); - for (int i = 0; i < 6; i++) { - if (!data[i * 6].isEmpty()) { - network.addCellTower(CellTower.from( - Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]), - Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16), - Integer.parseInt(data[i * 6 + 4]))); - } - } - - position.setNetwork(network); - - return position; - } - - private Object decodePna(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_PNA, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - position.set(Position.KEY_ALARM, sentence.contains("PNA") ? Position.ALARM_POWER_ON : Position.ALARM_POWER_OFF); - - return position; - } - - private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - int reportType = parser.nextHexInt(); - if (type.equals("NMR")) { - 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 / 0x10, reportType % 0x10 == 1); - } else if (type.equals("IGL")) { - position.set(Position.KEY_IGNITION, reportType % 0x10 == 1); - } - - decodeLocation(position, parser); - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - } - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); - } - - decodeDeviceTime(position, parser); - - if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.writeAndFlush(new NetworkMessage("+SACK:" + parser.next() + "$", remoteAddress)); - } - - return position; - } - - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_BASIC, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - if (parser.hasNext()) { - int hdop = parser.nextInt(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - } - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - position.setTime(parser.nextDateTime()); - } - - if (parser.hasNext(4)) { - position.setNetwork(new Network(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt()))); - } - - decodeDeviceTime(position, parser); - - switch (type) { - case "TOW": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "IDL": - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case "PNA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "PFA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case "EPN": - case "MPN": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "EPF": - case "MPF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BPL": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "STT": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "SWG": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - break; - case "TMP": - case "TEM": - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case "JDR": - case "JDS": - position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); - break; - default: - break; - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = ((ByteBuf) msg).toString(StandardCharsets.US_ASCII); - - int typeIndex = sentence.indexOf(":GT"); - if (typeIndex < 0) { - return null; - } - - Object result; - String type = sentence.substring(typeIndex + 3, typeIndex + 6); - if (sentence.startsWith("+ACK")) { - result = decodeAck(channel, remoteAddress, sentence, type); - } else { - switch (type) { - case "INF": - result = decodeInf(channel, remoteAddress, sentence); - break; - case "OBD": - result = decodeObd(channel, remoteAddress, sentence); - break; - case "CAN": - result = decodeCan(channel, remoteAddress, sentence); - break; - case "FRI": - case "GEO": - case "STR": - result = decodeFri(channel, remoteAddress, sentence); - break; - case "ERI": - result = decodeEri(channel, remoteAddress, sentence); - break; - case "IGN": - 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; - case "WIF": - result = decodeWif(channel, remoteAddress, sentence); - break; - case "GSM": - result = decodeGsm(channel, remoteAddress, sentence); - break; - case "VER": - result = decodeVer(channel, remoteAddress, sentence); - break; - case "PNA": - case "PFA": - result = decodePna(channel, remoteAddress, sentence); - break; - default: - result = decodeOther(channel, remoteAddress, sentence, type); - break; - } - - if (result == null) { - result = decodeBasic(channel, remoteAddress, sentence, type); - } - - if (result != null) { - if (result instanceof Position) { - ((Position) result).set(Position.KEY_TYPE, type); - } else { - for (Position p : (List<Position>) result) { - p.set(Position.KEY_TYPE, type); - } - } - } - } - - return result; - } - -} diff --git a/src/org/traccar/protocol/GlobalSatProtocol.java b/src/org/traccar/protocol/GlobalSatProtocol.java deleted file mode 100644 index 5612515c9..000000000 --- a/src/org/traccar/protocol/GlobalSatProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GlobalSatProtocol extends BaseProtocol { - - public GlobalSatProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new GlobalSatProtocolDecoder(GlobalSatProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/org/traccar/protocol/GlobalSatProtocolDecoder.java deleted file mode 100644 index 3d4ab5760..000000000 --- a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -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 GlobalSatProtocolDecoder extends BaseProtocolDecoder { - - private String format0; - private String format1; - - public GlobalSatProtocolDecoder(Protocol protocol) { - super(protocol); - - format0 = Context.getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); - format1 = Context.getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); - } - - public void setFormat0(String format) { - format0 = format; - } - - public void setFormat1(String format) { - format1 = format; - } - - private Position decodeOriginal(Channel channel, SocketAddress remoteAddress, String sentence) { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("ACK\r", remoteAddress)); - } - - String format; - if (sentence.startsWith("GSr")) { - format = format0; - } else if (sentence.startsWith("GSh")) { - format = format1; - } else { - return null; - } - - // Check that message contains required parameters - if (!format.contains("B") || !format.contains("S") || !(format.contains("1") - || format.contains("2") || format.contains("3")) || !(format.contains("6") - || format.contains("7") || format.contains("8"))) { - return null; - } - - if (format.contains("*")) { - format = format.substring(0, format.indexOf('*')); - sentence = sentence.substring(0, sentence.indexOf('*')); - } - String[] values = sentence.split(","); - - Position position = new Position(getProtocolName()); - - for (int formatIndex = 0, valueIndex = 1; formatIndex < format.length() - && valueIndex < values.length; formatIndex++) { - String value = values[valueIndex]; - - switch (format.charAt(formatIndex)) { - case 'S': - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - break; - case 'A': - if (value.isEmpty()) { - position.setValid(false); - } else { - position.setValid(Integer.parseInt(value) != 1); - } - break; - case 'B': - DateBuilder dateBuilder = new DateBuilder() - .setDay(Integer.parseInt(value.substring(0, 2))) - .setMonth(Integer.parseInt(value.substring(2, 4))) - .setYear(Integer.parseInt(value.substring(4))); - value = values[++valueIndex]; - dateBuilder - .setHour(Integer.parseInt(value.substring(0, 2))) - .setMinute(Integer.parseInt(value.substring(2, 4))) - .setSecond(Integer.parseInt(value.substring(4))); - position.setTime(dateBuilder.getDate()); - break; - case 'C': - valueIndex += 1; - break; - case '1': - double longitude = Double.parseDouble(value.substring(1)); - if (value.charAt(0) == 'W') { - longitude = -longitude; - } - position.setLongitude(longitude); - break; - case '2': - longitude = Double.parseDouble(value.substring(4)) / 60; - longitude += Integer.parseInt(value.substring(1, 4)); - if (value.charAt(0) == 'W') { - longitude = -longitude; - } - position.setLongitude(longitude); - break; - case '3': - position.setLongitude(Double.parseDouble(value) * 0.000001); - break; - case '6': - double latitude = Double.parseDouble(value.substring(1)); - if (value.charAt(0) == 'S') { - latitude = -latitude; - } - position.setLatitude(latitude); - break; - case '7': - latitude = Double.parseDouble(value.substring(3)) / 60; - latitude += Integer.parseInt(value.substring(1, 3)); - if (value.charAt(0) == 'S') { - latitude = -latitude; - } - position.setLatitude(latitude); - break; - case '8': - position.setLatitude(Double.parseDouble(value) * 0.000001); - break; - case 'G': - position.setAltitude(Double.parseDouble(value)); - break; - case 'H': - position.setSpeed(Double.parseDouble(value)); - break; - case 'I': - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); - break; - case 'J': - position.setSpeed(UnitsConverter.knotsFromMph(Double.parseDouble(value))); - break; - case 'K': - position.setCourse(Double.parseDouble(value)); - break; - case 'N': - if (value.endsWith("mV")) { - position.set(Position.KEY_BATTERY, - Integer.parseInt(value.substring(0, value.length() - 2)) / 1000.0); - } else { - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value)); - } - break; - default: - // Unsupported - break; - } - - valueIndex += 1; - } - return position; - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$") - .number("(d+),") // imei - .number("d+,") // mode - .number("(d+),") // fix - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([EW])") - .number("(ddd)(dd.d+),") // longitude (dddmm.mmmm) - .expression("([NS])") - .number("(dd)(dd.d+),") // latitude (ddmm.mmmm) - .number("(d+.?d*),") // altitude - .number("(d+.?d*),") // speed - .number("(d+.?d*)?,") // course - .number("(d+)[,*]") // satellites - .number("(d+.?d*)") // hdop - .compile(); - - private Position decodeAlternative(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.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(!parser.next().equals("1")); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_HDOP, parser.nextDouble()); - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("GS")) { - return decodeOriginal(channel, remoteAddress, sentence); - } else if (sentence.startsWith("$")) { - return decodeAlternative(channel, remoteAddress, sentence); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/GnxProtocol.java b/src/org/traccar/protocol/GnxProtocol.java deleted file mode 100644 index 3576bf805..000000000 --- a/src/org/traccar/protocol/GnxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GnxProtocol extends BaseProtocol { - - public GnxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new GnxProtocolDecoder(GnxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java deleted file mode 100644 index c9c221a69..000000000 --- a/src/org/traccar/protocol/GnxProtocolDecoder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class GnxProtocolDecoder extends BaseProtocolDecoder { - - public GnxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d+),") // imei - .number("d+,") // length - .expression("([01]),") // history - .number("(dd)(dd)(dd),") // device time (hhmmss) - .number("(dd)(dd)(dd),") // device date (ddmmyy) - .number("(dd)(dd)(dd),") // fix time (hhmmss) - .number("(dd)(dd)(dd),") // fix date (ddmmyy) - .number("(d),") // valid - .number("(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd.d+),") // longitude - .expression("([EW]),") - .compile(); - - private static final Pattern PATTERN_MIF = new PatternBuilder() - .text("$GNX_MIF,") - .expression(PATTERN_LOCATION.pattern()) - .expression("[01],") // valid card - .expression("([^,]+),") // rfid - .any() - .compile(); - - private static final Pattern PATTERN_OTHER = new PatternBuilder() - .text("$GNX_") - .expression("...,") - .expression(PATTERN_LOCATION.pattern()) - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - String type = sentence.substring(5, 8); - - Pattern pattern; - if (type.equals("MIF")) { - pattern = PATTERN_MIF; - } else { - pattern = PATTERN_OTHER; - } - - 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.setDeviceId(deviceSession.getDeviceId()); - - if (parser.nextInt(0) == 1) { - position.set(Position.KEY_ARCHIVE, true); - } - - position.setDeviceTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY, "GMT+5:30")); - position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY, "GMT+5:30")); - - position.setValid(parser.nextInt(0) != 0); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - - if (type.equals("MIF")) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/GoSafeProtocol.java b/src/org/traccar/protocol/GoSafeProtocol.java deleted file mode 100644 index 853b78a16..000000000 --- a/src/org/traccar/protocol/GoSafeProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GoSafeProtocol extends BaseProtocol { - - public GoSafeProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/org/traccar/protocol/GoSafeProtocolDecoder.java deleted file mode 100644 index 95ef18f20..000000000 --- a/src/org/traccar/protocol/GoSafeProtocolDecoder.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class GoSafeProtocolDecoder extends BaseProtocolDecoder { - - public GoSafeProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*GS") // header - .number("d+,") // protocol version - .number("(d+),") // imei - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("([^#]*)#?") // data - .compile(); - - private static final Pattern PATTERN_OLD = new PatternBuilder() - .text("*GS") // header - .number("d+,") // protocol version - .number("(d+),") // imei - .text("GPS:") - .number("(dd)(dd)(dd);") // time (hhmmss) - .number("d;").optional() // fix type - .expression("([AV]);") // validity - .number("([NS])(d+.d+);") // latitude - .number("([EW])(d+.d+);") // longitude - .number("(d+)?;") // speed - .number("(d+);") // course - .number("(d+.?d*)").optional() // hdop - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .compile(); - - private void decodeFragment(Position position, String fragment) { - int dataIndex = fragment.indexOf(':'); - int index = 0; - String[] values; - if (fragment.length() == dataIndex + 1) { - values = new String[0]; - } else { - 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++])); - if (index < values.length) { - 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, Long.parseLong(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; - } - } - - private Object decodeData(DeviceSession deviceSession, Date time, String data) { - - List<Position> positions = new LinkedList<>(); - Position position = null; - int index = 0; - String[] fragments = data.split(","); - - while (index < fragments.length) { - - if (fragments[index].isEmpty() || Character.isDigit(fragments[index].charAt(0))) { - - if (position != null) { - positions.add(position); - } - - position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(time); - - if (!fragments[index++].isEmpty()) { - position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index - 1])); - } - - } else { - - decodeFragment(position, fragments[index++]); - - } - - } - - if (position != null) { - positions.add(position); - } - - return positions; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("1234", remoteAddress)); - } - - String sentence = (String) msg; - Pattern pattern = PATTERN; - if (sentence.startsWith("*GS02")) { - pattern = PATTERN_OLD; - } - - Parser parser = new Parser(pattern, (String) msg); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - if (pattern == PATTERN_OLD) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - 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.set(Position.KEY_HDOP, parser.next()); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - - } else { - - Date time = new Date(); - if (parser.hasNext(6)) { - time = parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY); - } - - return decodeData(deviceSession, time, parser.next()); - - } - } - -} diff --git a/src/org/traccar/protocol/GotopProtocol.java b/src/org/traccar/protocol/GotopProtocol.java deleted file mode 100644 index 07fe02248..000000000 --- a/src/org/traccar/protocol/GotopProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GotopProtocol extends BaseProtocol { - - public GotopProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new GotopProtocolDecoder(GotopProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GotopProtocolDecoder.java b/src/org/traccar/protocol/GotopProtocolDecoder.java deleted file mode 100644 index 2ef975fe5..000000000 --- a/src/org/traccar/protocol/GotopProtocolDecoder.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 GotopProtocolDecoder extends BaseProtocolDecoder { - - public GotopProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(d+),") // imei - .expression("[^,]+,") // type - .expression("([AV]),") // validity - .number("DATE:(dd)(dd)(dd),") // date (yyddmm) - .number("TIME:(dd)(dd)(dd),") // time (hhmmss) - .number("LAT:(d+.d+)([NS]),") // latitude - .number("LOT:(d+.d+)([EW]),") // longitude - .text("Speed:").number("(d+.d+),") // speed - .expression("([^,]+),") // status - .number("(d+)?") // course - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.next().equals("A")); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - - position.set(Position.KEY_STATUS, parser.next()); - - position.setCourse(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Gps056FrameDecoder.java b/src/org/traccar/protocol/Gps056FrameDecoder.java deleted file mode 100644 index 0d84bf231..000000000 --- a/src/org/traccar/protocol/Gps056FrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -import java.nio.charset.StandardCharsets; - -public class Gps056FrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_HEADER = 4; - - @Override - protected Object decode( - 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) { - ByteBuf frame = buf.readRetainedSlice(length); - while (buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) != '$') { - buf.readByte(); - } - return frame; - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Gps056Protocol.java b/src/org/traccar/protocol/Gps056Protocol.java deleted file mode 100644 index b6ab10a19..000000000 --- a/src/org/traccar/protocol/Gps056Protocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class Gps056Protocol extends BaseProtocol { - - public Gps056Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Gps056FrameDecoder()); - pipeline.addLast(new Gps056ProtocolDecoder(Gps056Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/org/traccar/protocol/Gps056ProtocolDecoder.java deleted file mode 100644 index 0ba79bb51..000000000 --- a/src/org/traccar/protocol/Gps056ProtocolDecoder.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; - -public class Gps056ProtocolDecoder extends BaseProtocolDecoder { - - public Gps056ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static void sendResponse(Channel channel, String type, String imei, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - String header = "*" + type + imei; - response.writeBytes(header.getBytes(StandardCharsets.US_ASCII)); - if (content != null) { - response.writeBytes(content); - } - response.writeByte('#'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - 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; - byte hemisphere = buf.readByte(); - if (hemisphere == 'S' || hemisphere == 'W') { - degrees = -degrees; - } - return degrees; - } - - 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, buf.readShortLE() * 5.06); // mV - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.skipBytes(2); // length - - 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) { - return null; - } - - if (type.startsWith("LOGN")) { - - 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")) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - - position.setValid(true); - position.setTime(dateBuilder.getDate()); - position.setLatitude(decodeCoordinate(buf)); - position.setLongitude(decodeCoordinate(buf)); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedShort()); - - decodeStatus(buf, position); - - sendResponse(channel, "GPSA" + type.substring(4), imei, buf.readSlice(2)); - - return position; - - } else if (type.startsWith("SYNC")) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - decodeStatus(buf, position); - - sendResponse(channel, "SYSA" + type.substring(4), imei, null); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Gps103Protocol.java b/src/org/traccar/protocol/Gps103Protocol.java deleted file mode 100644 index 6272a3fd1..000000000 --- a/src/org/traccar/protocol/Gps103Protocol.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class Gps103Protocol extends BaseProtocol { - - public Gps103Protocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_POSITION_STOP, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM, - Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gps103ProtocolEncoder()); - pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gps103ProtocolEncoder()); - pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java deleted file mode 100644 index aa02e8ad4..000000000 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * 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.protocol; - -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.Protocol; -import org.traccar.helper.DataConverter; -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 { - - private int photoPackets = 0; - private ByteBuf photo; - - public Gps103ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .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 - .groupBegin() - .text("L,,,") - .number("(x+),,") // lac - .number("(x+),,,") // cid - .or() - .text("F,") - .groupBegin() - .number("(dd)(dd)(dd).d+") // time utc (hhmmss) - .or() - .number("(?:d{1,5}.d+)?") - .groupEnd() - .text(",") - .expression("([AV]),") // validity - .expression("([NS]),").optional() - .number("(d+)(dd.d+),") // latitude (ddmm.mmmm) - .expression("([NS]),").optional() - .expression("([EW]),").optional() - .number("(d+)(dd.d+),") // longitude (dddmm.mmmm) - .expression("([EW])?,").optional() - .number("(d+.?d*)?").optional() // speed - .number(",(d+.?d*)?").optional() // course - .number(",(d+.?d*)?").optional() // altitude - .number(",([01])?").optional() // ignition - .number(",([01])?").optional() // door - .groupBegin() - .number(",(?:(d+.d+)%)?") // fuel 1 - .number(",(?:(d+.d+)%|d+)?") // fuel 2 - .groupEnd("?") - .number(",([-+]?d+)?").optional() // temperature - .groupEnd() - .any() - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .text("imei:") - .number("(d+),") // imei - .expression("OBD,") // type - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+)?,") // odometer - .number("(d+.d+)?,") // fuel instant - .number("(d+.d+)?,") // fuel average - .number("(d+)?,") // hours - .number("(d+),") // speed - .number("(d+.?d*%),") // power load - .number("(?:([-+]?d+)|[-+]?),") // temperature - .number("(d+.?d*%),") // throttle - .number("(d+),") // rpm - .number("(d+.d+),") // battery - .number("([^;]*)") // dtcs - .any() - .compile(); - - private static final Pattern PATTERN_ALT = new PatternBuilder() - .text("imei:") - .number("(d+),") // imei - .expression("[^,]+,") - .expression("(?:-+|(.+)),") // event - .expression("(?:-+|(.+)),") // sensor id - .expression("(?:-+|(.+)),") // sensor voltage - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(d+),") // rssi - .number("(d),") // gps status - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(-?d+),") // altitude - .number("(d+.d+),") // hdop - .number("(d+),") // satellites - .number("([01]),") // ignition - .number("([01]),") // charge - .expression("(?:-+|(.+))") // error - .any() - .compile(); - - private String decodeAlarm(String value) { - if (value.startsWith("T:")) { - return Position.ALARM_TEMPERATURE; - } else if (value.startsWith("oil")) { - return Position.ALARM_FUEL_LEAK; - } - switch (value) { - case "tracker": - return null; - case "help me": - return Position.ALARM_SOS; - case "low battery": - return Position.ALARM_LOW_BATTERY; - case "stockade": - return Position.ALARM_GEOFENCE; - case "move": - return Position.ALARM_MOVEMENT; - case "speed": - return Position.ALARM_OVERSPEED; - case "acc on": - return Position.ALARM_POWER_ON; - case "acc off": - return Position.ALARM_POWER_OFF; - case "door alarm": - return Position.ALARM_DOOR; - case "ac alarm": - return Position.ALARM_POWER_CUT; - case "accident alarm": - return Position.ALARM_ACCIDENT; - case "sensor alarm": - return Position.ALARM_SHOCK; - case "bonnet alarm": - return Position.ALARM_BONNET; - case "footbrake alarm": - return Position.ALARM_FOOT_BRAKE; - case "DTC": - return Position.ALARM_FAULT; - default: - return null; - } - } - - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - String imei = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - 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.writeAndFlush(new NetworkMessage("**,imei:" + imei + ",E;", remoteAddress)); - } - } else if (alarm.startsWith("vt")) { - photoPackets = Integer.parseInt(alarm.substring(2)); - photo = Unpooled.buffer(); - } else if (alarm.equals("acc on")) { - position.set(Position.KEY_IGNITION, true); - } else if (alarm.equals("acc off")) { - position.set(Position.KEY_IGNITION, false); - } else if (alarm.startsWith("T:")) { - position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(alarm.substring(2))); - } else if (alarm.startsWith("oil ")) { - 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); - } - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - int localHours = parser.nextInt(0); - int localMinutes = parser.nextInt(0); - - String rfid = parser.next(); - if (alarm.equals("rfid")) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); - } - - if (parser.hasNext(2)) { - - getLastLocation(position, null); - - 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); - } - 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; - } - - 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()); - - 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; - } - - - private Position decodeAlternative(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_ALT, 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()); - - position.set(Position.KEY_EVENT, parser.next()); - position.set("sensorId", parser.next()); - position.set("sensorVoltage", parser.nextDouble()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.set(Position.KEY_RSSI, parser.nextInt()); - - position.setValid(parser.nextInt() > 0); - 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_HDOP, parser.nextDouble()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); - position.set(Position.KEY_CHARGE, parser.nextInt() > 0); - position.set("error", parser.next()); - - return position; - } - - private Position decodePhoto(Channel channel, SocketAddress remoteAddress, String sentence) { - - String imei = sentence.substring(5, 5 + 15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex( - sentence.substring(24, sentence.endsWith(";") ? sentence.length() - 1 : sentence.length()))); - int index = buf.readUnsignedShortLE(); - photo.writeBytes(buf, buf.readerIndex() + 2, buf.readableBytes() - 4); - - if (index + 1 >= photoPackets) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); - } finally { - photoPackets = 0; - photo.release(); - photo = null; - } - - return position; - } else { - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.contains("imei:") && sentence.length() <= 30) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("LOAD", remoteAddress)); - Matcher matcher = Pattern.compile("imei:(\\d+),").matcher(sentence); - if (matcher.find()) { - 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.substring(21, 21 + 2).equals("vr")) { - return decodePhoto(channel, remoteAddress, sentence); - } else if (sentence.substring(21, 21 + 3).contains("OBD")) { - return decodeObd(channel, remoteAddress, sentence); - } else if (sentence.endsWith("*")) { - return decodeAlternative(channel, remoteAddress, sentence); - } else { - return decodeRegular(channel, remoteAddress, sentence); - } - } - -} diff --git a/src/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/org/traccar/protocol/Gps103ProtocolEncoder.java deleted file mode 100644 index 47ef2f333..000000000 --- a/src/org/traccar/protocol/Gps103ProtocolEncoder.java +++ /dev/null @@ -1,68 +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.protocol; - -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class Gps103ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { - - @Override - public String formatValue(String key, Object value) { - - if (key.equals(Command.KEY_FREQUENCY)) { - long frequency = ((Number) value).longValue(); - if (frequency / 60 / 60 > 0) { - return String.format("%02dh", frequency / 60 / 60); - } else if (frequency / 60 > 0) { - return String.format("%02dm", frequency / 60); - } else { - return String.format("%02ds", frequency); - } - } - - return null; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "**,imei:{%s},{%s}", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - case Command.TYPE_POSITION_STOP: - return formatCommand(command, "**,imei:{%s},A", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "**,imei:{%s},B", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand( - command, "**,imei:{%s},C,{%s}", this, Command.KEY_UNIQUE_ID, Command.KEY_FREQUENCY); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "**,imei:{%s},J", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "**,imei:{%s},K", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "**,imei:{%s},L", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "**,imei:{%s},M", Command.KEY_UNIQUE_ID); - case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "**,imei:{%s},160", Command.KEY_UNIQUE_ID); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/GpsGateProtocol.java b/src/org/traccar/protocol/GpsGateProtocol.java deleted file mode 100644 index a131b6f48..000000000 --- a/src/org/traccar/protocol/GpsGateProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GpsGateProtocol extends BaseProtocol { - - public GpsGateProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new GpsGateProtocolDecoder(GpsGateProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/org/traccar/protocol/GpsGateProtocolDecoder.java deleted file mode 100644 index cc187225b..000000000 --- a/src/org/traccar/protocol/GpsGateProtocolDecoder.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Checksum; -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.util.regex.Pattern; - -public class GpsGateProtocolDecoder extends BaseProtocolDecoder { - - public GpsGateProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_GPRMC = new PatternBuilder() - .text("$GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .compile(); - - private static final Pattern PATTERN_FRCMD = new PatternBuilder() - .text("$FRCMD,") - .number("(d+),") // imei - .expression("[^,]*,") // command - .expression("[^,]*,") - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*),") // altitude - .number("(d+.?d*),") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([01])") // validity - .any() - .compile(); - - private void send(Channel channel, SocketAddress remoteAddress, String message) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(message + Checksum.nmea(message) + "\r\n", remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("$FRLIN,")) { - - int beginIndex = sentence.indexOf(',', 7); - if (beginIndex != -1) { - beginIndex += 1; - int endIndex = sentence.indexOf(',', beginIndex); - if (endIndex != -1) { - String imei = sentence.substring(beginIndex, endIndex); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null) { - if (channel != null) { - send(channel, remoteAddress, "$FRSES," + channel.id().asShortText()); - } - } else { - send(channel, remoteAddress, "$FRERR,AuthError,Unknown device"); - } - } else { - send(channel, remoteAddress, "$FRERR,AuthError,Parse error"); - } - } else { - send(channel, remoteAddress, "$FRERR,AuthError,Parse error"); - } - - } else if (sentence.startsWith("$FRVER,")) { - - send(channel, remoteAddress, "$FRVER,1,0,GpsGate Server 1.0"); - - } else if (sentence.startsWith("$GPRMC,")) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN_GPRMC, sentence); - if (!parser.matches()) { - 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)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - - } else if (sentence.startsWith("$FRCMD,")) { - - Parser parser = new Parser(PATTERN_FRCMD, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("1")); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/GpsMarkerProtocol.java b/src/org/traccar/protocol/GpsMarkerProtocol.java deleted file mode 100644 index ad23ece48..000000000 --- a/src/org/traccar/protocol/GpsMarkerProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class GpsMarkerProtocol extends BaseProtocol { - - public GpsMarkerProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new GpsMarkerProtocolDecoder(GpsMarkerProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java deleted file mode 100644 index bbb2c31e2..000000000 --- a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class GpsMarkerProtocolDecoder extends BaseProtocolDecoder { - - public GpsMarkerProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$GM") - .number("d") // type - .number("(?:xx)?") // index - .number("(d{15})") // imei - .number("T(dd)(dd)(dd)") // date (ddmmyy) - .number("(dd)(dd)(dd)?") // time (hhmmss) - .expression("([NS])") - .number("(dd)(dd)(dddd)") // latitude - .expression("([EW])") - .number("(ddd)(dd)(dddd)") // longitude - .number("(ddd)") // speed - .number("(ddd)") // course - .number("(x)") // satellites - .number("(dd)") // battery - .number("(d)") // input - .number("(d)") // output - .number("(ddd)") // temperature - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_MIN)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextHexInt(0)); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/GpsmtaProtocol.java b/src/org/traccar/protocol/GpsmtaProtocol.java deleted file mode 100644 index ce6cc5929..000000000 --- a/src/org/traccar/protocol/GpsmtaProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class GpsmtaProtocol extends BaseProtocol { - - public GpsmtaProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/org/traccar/protocol/GpsmtaProtocolDecoder.java deleted file mode 100644 index 31f9401b4..000000000 --- a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; -import java.util.regex.Pattern; - -public class GpsmtaProtocolDecoder extends BaseProtocolDecoder { - - public GpsmtaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("([^ ]+) ") // uid - .number("(d+) ") // time (unix time) - .number("(-?d+.d+) ") // latitude - .number("(-?d+.d+) ") // longitude - .number("(d+) ") // speed - .number("(d+) ") // course - .number("(d+) ") // accuracy - .number("(d+) ") // altitude - .number("(d+) ") // flags - .number("(d+) ") // battery - .number("(d+) ") // temperature - .number("(d)") // charging status - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - String time = parser.next(); - position.setTime(new Date(Long.parseLong(time) * 1000)); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(parser.nextInt()); - position.setCourse(parser.nextInt()); - position.setAccuracy(parser.nextInt()); - position.setAltitude(parser.nextInt()); - - position.set(Position.KEY_STATUS, parser.nextInt()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.KEY_CHARGE, parser.nextInt() == 1); - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(time, remoteAddress)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/GranitFrameDecoder.java b/src/org/traccar/protocol/GranitFrameDecoder.java deleted file mode 100644 index bb7f4be44..000000000 --- a/src/org/traccar/protocol/GranitFrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; -import org.traccar.helper.BufferUtil; - -public class GranitFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - int indexEnd = BufferUtil.indexOf("\r\n", buf); - if (indexEnd != -1) { - int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '~'); - if (indexTilde != -1 && indexTilde < indexEnd) { - int length = buf.getUnsignedShortLE(indexTilde + 1); - indexEnd = BufferUtil.indexOf("\r\n", buf, indexTilde + 2 + length, buf.writerIndex()); - if (indexEnd == -1) { - return null; - } - } - ByteBuf frame = buf.readRetainedSlice(indexEnd - buf.readerIndex()); - buf.skipBytes(2); - return frame; - } - return null; - } - -} diff --git a/src/org/traccar/protocol/GranitProtocol.java b/src/org/traccar/protocol/GranitProtocol.java deleted file mode 100644 index 6785f2a2e..000000000 --- a/src/org/traccar/protocol/GranitProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class GranitProtocol extends BaseProtocol { - - public GranitProtocol() { - setSupportedDataCommands( - Command.TYPE_IDENTIFICATION, - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_POSITION_SINGLE); - setTextCommandEncoder(new GranitProtocolSmsEncoder()); - setSupportedTextCommands( - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new GranitFrameDecoder()); - pipeline.addLast(new GranitProtocolEncoder()); - pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/GranitProtocolDecoder.java b/src/org/traccar/protocol/GranitProtocolDecoder.java deleted file mode 100644 index 8900e5b39..000000000 --- a/src/org/traccar/protocol/GranitProtocolDecoder.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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. - * 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.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class GranitProtocolDecoder extends BaseProtocolDecoder { - - private static final int HEADER_LENGTH = 6; - - private double adc1Ratio; - private double adc2Ratio; - private double adc3Ratio; - private double adc4Ratio; - - public GranitProtocolDecoder(Protocol protocol) { - super(protocol); - adc1Ratio = Context.getConfig().getDouble("granit.adc1Ratio", 1); - adc2Ratio = Context.getConfig().getDouble("granit.adc2Ratio", 1); - adc3Ratio = Context.getConfig().getDouble("granit.adc3Ratio", 1); - adc4Ratio = Context.getConfig().getDouble("granit.adc4Ratio", 1); - } - - public static void appendChecksum(ByteBuf buffer, int length) { - buffer.writeByte('*'); - 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) { - ByteBuf response = Unpooled.buffer(); - response.writeBytes("BB+UGRC~".getBytes(StandardCharsets.US_ASCII)); - response.writeShortLE(6); // length - response.writeInt((int) time); - response.writeShortLE(deviceId); - appendChecksum(response, 16); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - - private static void sendResponseArchive(Channel channel, int deviceId, int packNum) { - ByteBuf response = Unpooled.buffer(); - response.writeBytes("BB+ARCF~".getBytes(StandardCharsets.US_ASCII)); - response.writeShortLE(4); // length - response.writeShortLE(packNum); - response.writeShortLE(deviceId); - appendChecksum(response, 14); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - - private void decodeStructure(ByteBuf buf, Position position) { - short flags = buf.readUnsignedByte(); - position.setValid(BitUtil.check(flags, 7)); - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - - short satDel = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, BitUtil.from(satDel, 4)); - - int pdop = BitUtil.to(satDel, 4); - position.set(Position.KEY_PDOP, pdop); - - int lonDegrees = buf.readUnsignedByte(); - int latDegrees = buf.readUnsignedByte(); - int lonMinutes = buf.readUnsignedShortLE(); - int latMinutes = buf.readUnsignedShortLE(); - - double latitude = latDegrees + latMinutes / 60000.0; - double longitude = lonDegrees + lonMinutes / 60000.0; - - if (position.getValid()) { - if (!BitUtil.check(flags, 4)) { - latitude = -latitude; - } - if (!BitUtil.check(flags, 5)) { - longitude = -longitude; - } - } - - position.setLongitude(longitude); - position.setLatitude(latitude); - - position.setSpeed(buf.readUnsignedByte()); - - int course = buf.readUnsignedByte(); - if (BitUtil.check(flags, 6)) { - course = course | 0x100; - } - position.setCourse(course); - - position.set(Position.KEY_DISTANCE, buf.readShortLE()); - - int analogIn1 = buf.readUnsignedByte(); - int analogIn2 = buf.readUnsignedByte(); - int analogIn3 = buf.readUnsignedByte(); - int analogIn4 = buf.readUnsignedByte(); - - int analogInHi = buf.readUnsignedByte(); - - analogIn1 = analogInHi << 8 & 0x300 | analogIn1; - analogIn2 = analogInHi << 6 & 0x300 | analogIn2; - analogIn3 = analogInHi << 4 & 0x300 | analogIn3; - analogIn4 = analogInHi << 2 & 0x300 | analogIn4; - - position.set(Position.PREFIX_ADC + 1, analogIn1 * adc1Ratio); - position.set(Position.PREFIX_ADC + 2, analogIn2 * adc2Ratio); - position.set(Position.PREFIX_ADC + 3, analogIn3 * adc3Ratio); - position.set(Position.PREFIX_ADC + 4, analogIn4 * adc4Ratio); - - position.setAltitude(buf.readUnsignedByte() * 10); - - int output = buf.readUnsignedByte(); - for (int i = 0; i < 8; i++) { - position.set(Position.PREFIX_IO + (i + 1), BitUtil.check(output, i)); - } - buf.readUnsignedByte(); // status message buffer - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int indexTilde = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '~'); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - - if (deviceSession != null && indexTilde == -1) { - String bufString = buf.toString(StandardCharsets.US_ASCII); - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date()); - getLastLocation(position, new Date()); - position.setValid(false); - position.set(Position.KEY_RESULT, bufString); - return position; - } - - if (buf.readableBytes() < HEADER_LENGTH) { - return null; - } - String header = buf.readSlice(HEADER_LENGTH).toString(StandardCharsets.US_ASCII); - - if (header.equals("+RRCB~")) { - - 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.readUnsignedIntLE(); - if (channel != null) { - sendResponseCurrent(channel, deviceId, unixTime); - } - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(unixTime * 1000)); - - decodeStructure(buf, position); - return position; - - } else if (header.equals("+DDAT~")) { - - buf.skipBytes(2); // binary length - int deviceId = buf.readUnsignedShortLE(); - deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); - if (deviceSession == null) { - return null; - } - byte format = buf.readByte(); - if (format != 4) { - return null; - } - byte nblocks = buf.readByte(); - int packNum = buf.readUnsignedShortLE(); - if (channel != null) { - sendResponseArchive(channel, deviceId, packNum); - } - List<Position> positions = new ArrayList<>(); - while (nblocks > 0) { - nblocks--; - 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()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(new Date((unixTime + i * timeIncrement) * 1000)); - decodeStructure(buf, position); - position.set(Position.KEY_ARCHIVE, true); - positions.add(position); - } else { - buf.skipBytes(20); // skip filled 0xFE structure - } - } - buf.skipBytes(2); // increment - } - return positions; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/GranitProtocolEncoder.java b/src/org/traccar/protocol/GranitProtocolEncoder.java deleted file mode 100644 index 6345ff971..000000000 --- a/src/org/traccar/protocol/GranitProtocolEncoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - * 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 java.nio.charset.StandardCharsets; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.traccar.BaseProtocolEncoder; -import org.traccar.model.Command; - -public class GranitProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeCommand(String commandString) { - ByteBuf buffer = Unpooled.buffer(); - buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); - GranitProtocolDecoder.appendChecksum(buffer, commandString.length()); - return buffer; - } - - @Override - protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_IDENTIFICATION: - return encodeCommand("BB+IDNT"); - case Command.TYPE_REBOOT_DEVICE: - return encodeCommand("BB+RESET"); - case Command.TYPE_POSITION_SINGLE: - return encodeCommand("BB+RRCD"); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/org/traccar/protocol/GranitProtocolSmsEncoder.java deleted file mode 100644 index 7d5518c17..000000000 --- a/src/org/traccar/protocol/GranitProtocolSmsEncoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.model.Command; - -public class GranitProtocolSmsEncoder extends StringProtocolEncoder { - - @Override - protected String encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return "BB+RESET"; - case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "BB+BBMD={%s}", Command.KEY_FREQUENCY); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Gt02Protocol.java b/src/org/traccar/protocol/Gt02Protocol.java deleted file mode 100644 index f412ee720..000000000 --- a/src/org/traccar/protocol/Gt02Protocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class Gt02Protocol extends BaseProtocol { - - public Gt02Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); - pipeline.addLast(new Gt02ProtocolDecoder(Gt02Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/org/traccar/protocol/Gt02ProtocolDecoder.java deleted file mode 100644 index 78a3fd3ee..000000000 --- a/src/org/traccar/protocol/Gt02ProtocolDecoder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.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.Protocol; -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.charset.StandardCharsets; - -public class Gt02ProtocolDecoder extends BaseProtocolDecoder { - - public Gt02ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_DATA = 0x10; - public static final int MSG_HEARTBEAT = 0x1A; - public static final int MSG_RESPONSE = 0x1C; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readByte(); // size - - Position position = new Position(getProtocolName()); - - // Zero for location messages - int power = buf.readUnsignedByte(); - int gsm = buf.readUnsignedByte(); - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); - - int type = buf.readUnsignedByte(); - - if (type == MSG_HEARTBEAT) { - - getLastLocation(position, null); - - position.set(Position.KEY_POWER, power); - position.set(Position.KEY_RSSI, gsm); - - if (channel != null) { - byte[] response = {0x54, 0x68, 0x1A, 0x0D, 0x0A}; - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); - } - - } else if (type == MSG_DATA) { - - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - double latitude = buf.readUnsignedInt() / (60.0 * 30000.0); - double longitude = buf.readUnsignedInt() / (60.0 * 30000.0); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedShort()); - - buf.skipBytes(3); // reserved - - long flags = buf.readUnsignedInt(); - position.setValid(BitUtil.check(flags, 0)); - if (!BitUtil.check(flags, 1)) { - latitude = -latitude; - } - if (!BitUtil.check(flags, 2)) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - - } else if (type == MSG_RESPONSE) { - - getLastLocation(position, null); - - position.set(Position.KEY_RESULT, - buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); - - } else { - - return null; - - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java deleted file mode 100644 index cc934be42..000000000 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - * 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 Gt06FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 5) { - return null; - } - - int length = 2 + 2; // head and tail - - if (buf.getByte(buf.readerIndex()) == 0x78) { - length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2); - } else { - length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); - } - - if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { - 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.readRetainedSlice(endIndex + 2 - buf.readerIndex()); - } - } while (endIndex > 0); - - return null; - } - -} diff --git a/src/org/traccar/protocol/Gt06Protocol.java b/src/org/traccar/protocol/Gt06Protocol.java deleted file mode 100644 index 6e5435cd4..000000000 --- a/src/org/traccar/protocol/Gt06Protocol.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class Gt06Protocol extends BaseProtocol { - - public Gt06Protocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Gt06FrameDecoder()); - pipeline.addLast(new Gt06ProtocolEncoder()); - pipeline.addLast(new Gt06ProtocolDecoder(Gt06Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java deleted file mode 100644 index 1f8fb66dd..000000000 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BcdUtil; -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; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.CellTower; -import org.traccar.model.Device; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; -import java.util.TimeZone; -import java.util.regex.Pattern; - -public class Gt06ProtocolDecoder extends BaseProtocolDecoder { - - private final Map<Integer, ByteBuf> photos = new HashMap<>(); - - public Gt06ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN = 0x01; - public static final int MSG_GPS = 0x10; - public static final int MSG_LBS = 0x11; - public static final int MSG_GPS_LBS_1 = 0x12; - public static final int MSG_GPS_LBS_2 = 0x22; - public static final int MSG_STATUS = 0x13; - public static final int MSG_SATELLITE = 0x14; - public static final int MSG_STRING = 0x15; - public static final int MSG_GPS_LBS_STATUS_1 = 0x16; - public static final int MSG_WIFI = 0x17; - public static final int MSG_GPS_LBS_STATUS_2 = 0x26; - public static final int MSG_GPS_LBS_STATUS_3 = 0x27; - public static final int MSG_LBS_MULTIPLE = 0x28; - public static final int MSG_LBS_WIFI = 0x2C; - public static final int MSG_LBS_EXTEND = 0x18; - public static final int MSG_LBS_STATUS = 0x19; - public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; - public static final int MSG_HEARTBEAT = 0x23; - public static final int MSG_ADDRESS_REQUEST = 0x2A; - public static final int MSG_ADDRESS_RESPONSE = 0x97; - public static final int MSG_AZ735_GPS = 0x32; - public static final int MSG_AZ735_ALARM = 0x33; - public static final int MSG_X1_GPS = 0x34; - public static final int MSG_X1_PHOTO_INFO = 0x35; - public static final int MSG_X1_PHOTO_DATA = 0x36; - public static final int MSG_WIFI_2 = 0x69; - public static final int MSG_COMMAND_0 = 0x80; - public static final int MSG_COMMAND_1 = 0x81; - public static final int MSG_COMMAND_2 = 0x82; - public static final int MSG_TIME_REQUEST = 0x8A; - public static final int MSG_INFO = 0x94; - public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; - public static final int MSG_LBS_2 = 0xA1; - public static final int MSG_WIFI_3 = 0xA2; - public static final int MSG_FENCE_SINGLE = 0xA3; - public static final int MSG_FENCE_MULTI = 0xA4; - public static final int MSG_LBS_ALARM = 0xA5; - public static final int MSG_LBS_ADDRESS = 0xA7; - public static final int MSG_OBD = 0x8C; - public static final int MSG_DTC = 0x65; - public static final int MSG_PID = 0x66; - - private static boolean isSupported(int type) { - return hasGps(type) || hasLbs(type) || hasStatus(type); - } - - private static boolean hasGps(int type) { - switch (type) { - case MSG_GPS: - case MSG_GPS_LBS_1: - case MSG_GPS_LBS_2: - case MSG_GPS_LBS_STATUS_1: - case MSG_GPS_LBS_STATUS_2: - case MSG_GPS_LBS_STATUS_3: - case MSG_GPS_PHONE: - case MSG_GPS_LBS_EXTEND: - case MSG_GPS_2: - case MSG_FENCE_SINGLE: - case MSG_FENCE_MULTI: - return true; - default: - return false; - } - } - - private static boolean hasLbs(int type) { - switch (type) { - case MSG_LBS: - case MSG_LBS_STATUS: - case MSG_GPS_LBS_1: - case MSG_GPS_LBS_2: - case MSG_GPS_LBS_STATUS_1: - case MSG_GPS_LBS_STATUS_2: - case MSG_GPS_LBS_STATUS_3: - case MSG_GPS_2: - case MSG_FENCE_SINGLE: - case MSG_FENCE_MULTI: - case MSG_LBS_ALARM: - case MSG_LBS_ADDRESS: - return true; - default: - return false; - } - } - - private static boolean hasStatus(int type) { - switch (type) { - case MSG_STATUS: - case MSG_LBS_STATUS: - case MSG_GPS_LBS_STATUS_1: - case MSG_GPS_LBS_STATUS_2: - case MSG_GPS_LBS_STATUS_3: - return true; - default: - return false; - } - } - - private static boolean hasLanguage(int type) { - switch (type) { - case MSG_GPS_PHONE: - case MSG_HEARTBEAT: - case MSG_GPS_LBS_STATUS_3: - case MSG_LBS_MULTIPLE: - case MSG_LBS_2: - case MSG_FENCE_MULTI: - return true; - default: - return false; - } - } - - private void sendResponse(Channel channel, boolean extended, int type, int index, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - int length = 5 + (content != null ? content.readableBytes() : 0); - if (extended) { - response.writeShort(0x7979); - response.writeShort(length); - } else { - response.writeShort(0x7878); - response.writeByte(length); - } - response.writeByte(type); - if (content != null) { - response.writeBytes(content); - content.release(); - } - response.writeShort(index); - response.writeShort(Checksum.crc16(Checksum.CRC16_X25, - response.nioBuffer(2, response.writerIndex() - 2))); - response.writeByte('\r'); response.writeByte('\n'); // ending - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private void sendPhotoRequest(Channel channel, int pictureId) { - 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, ByteBuf buf, boolean hasLength, TimeZone timezone) { - - DateBuilder dateBuilder = new DateBuilder(timezone) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - if (hasLength && buf.readUnsignedByte() == 0) { - return false; - } - - position.set(Position.KEY_SATELLITES, BitUtil.to(buf.readUnsignedByte(), 4)); - - double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; - double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - int flags = buf.readUnsignedShort(); - position.setCourse(BitUtil.to(flags, 10)); - position.setValid(BitUtil.check(flags, 12)); - - if (!BitUtil.check(flags, 10)) { - latitude = -latitude; - } - if (BitUtil.check(flags, 11)) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - - if (BitUtil.check(flags, 14)) { - position.set(Position.KEY_IGNITION, BitUtil.check(flags, 15)); - } - - return true; - } - - private boolean decodeLbs(Position position, ByteBuf buf, boolean hasLength) { - - int length = 0; - if (hasLength) { - length = buf.readUnsignedByte(); - if (length == 0) { - return false; - } - } - - int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); - - position.setNetwork(new Network(CellTower.from( - BitUtil.to(mcc, 15), mnc, buf.readUnsignedShort(), buf.readUnsignedMedium()))); - - if (length > 9) { - buf.skipBytes(length - 9); - } - - return true; - } - - private boolean decodeStatus(Position position, ByteBuf buf) { - - int status = buf.readUnsignedByte(); - - position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 1)); - position.set(Position.KEY_CHARGE, BitUtil.check(status, 2)); - position.set(Position.KEY_BLOCKED, BitUtil.check(status, 7)); - - switch (BitUtil.between(status, 3, 6)) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case 7: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - default: - break; - } - - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - - return true; - } - - private String decodeAlarm(short value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x02: - return Position.ALARM_POWER_CUT; - case 0x03: - case 0x09: - return Position.ALARM_VIBRATION; - case 0x04: - return Position.ALARM_GEOFENCE_ENTER; - case 0x05: - return Position.ALARM_GEOFENCE_EXIT; - case 0x06: - return Position.ALARM_OVERSPEED; - case 0x0E: - case 0x0F: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_POWER_OFF; - case 0x13: - return Position.ALARM_TAMPERING; - case 0x14: - return Position.ALARM_DOOR; - case 0x29: - return Position.ALARM_ACCELERATION; - case 0x30: - return Position.ALARM_BRAKING; - case 0x2A: - case 0x2B: - return Position.ALARM_CORNERING; - case 0x2C: - return Position.ALARM_ACCIDENT; - case 0x23: - return Position.ALARM_FALL_DOWN; - default: - return null; - } - } - - private static final Pattern PATTERN_FUEL = new PatternBuilder() - .text("!AIOIL,") - .number("d+,") // device address - .number("d+.d+,") // output value - .number("(d+.d+),") // temperature - .expression("[^,]+,") // version - .number("dd") // back wave - .number("d") // software status code - .number("d,") // hardware status code - .number("(d+.d+),") // measured value - .expression("[01],") // movement status - .number("d+,") // excited wave times - .number("xx") // checksum - .compile(); - - private Position decodeFuelData(Position position, String sentence) { - Parser parser = new Parser(PATTERN_FUEL, sentence); - if (!parser.matches()) { - return null; - } - - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); - - return position; - } - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .text("Current position!") - .number("Lat:([NS])(d+.d+),") // latitude - .number("Lon:([EW])(d+.d+),") // longitude - .text("Course:").number("(d+.d+),") // course - .text("Speed:").number("(d+.d+),") // speed - .text("DateTime:") - .number("(dddd)-(dd)-(dd) +") // date - .number("(dd):(dd):(dd)") // time - .compile(); - - private Position decodeLocationString(Position position, String sentence) { - Parser parser = new Parser(PATTERN_LOCATION, sentence); - if (!parser.matches()) { - return null; - } - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setCourse(parser.nextDouble()); - position.setSpeed(parser.nextDouble()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); - - return position; - } - - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - int length = buf.readUnsignedByte(); - int dataLength = length - 5; - int type = buf.readUnsignedByte(); - - DeviceSession deviceSession = null; - if (type != MSG_LOGIN) { - deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); - } - } - - if (type == MSG_LOGIN) { - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - buf.readUnsignedShort(); // type - - deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); - } - - if (dataLength > 10) { - int extensionBits = buf.readUnsignedShort(); - int hours = (extensionBits >> 4) / 100; - int minutes = (extensionBits >> 4) % 100; - int offset = (hours * 60 + minutes) * 60; - if ((extensionBits & 0x8) != 0) { - offset = -offset; - } - if (deviceSession != null) { - TimeZone timeZone = deviceSession.getTimeZone(); - if (timeZone.getRawOffset() == 0) { - timeZone.setRawOffset(offset * 1000); - deviceSession.setTimeZone(timeZone); - } - } - - } - - if (deviceSession != null) { - sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); - } - - } else if (type == MSG_HEARTBEAT) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - int status = buf.readUnsignedByte(); - position.set(Position.KEY_ARMED, BitUtil.check(status, 0)); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 1)); - position.set(Position.KEY_CHARGE, BitUtil.check(status, 2)); - - 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; - - } else if (type == MSG_ADDRESS_REQUEST) { - - String response = "NA&&NA&&0##"; - ByteBuf content = Unpooled.buffer(); - content.writeByte(response.length()); - content.writeInt(0); - content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); - sendResponse(channel, true, MSG_ADDRESS_RESPONSE, 0, content); - - } else if (type == MSG_TIME_REQUEST) { - - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - 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)); - content.writeByte(calendar.get(Calendar.HOUR_OF_DAY)); - content.writeByte(calendar.get(Calendar.MINUTE)); - content.writeByte(calendar.get(Calendar.SECOND)); - sendResponse(channel, false, MSG_TIME_REQUEST, 0, content); - - } else if (type == MSG_X1_GPS || type == MSG_X1_PHOTO_INFO) { - - return decodeX1(channel, buf, deviceSession, type); - - } else if (type == MSG_WIFI || type == MSG_WIFI_2) { - - return decodeWifi(channel, buf, deviceSession, type); - - } else if (type == MSG_INFO) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_POWER, buf.readShort() * 0.01); - - return position; - - } else { - - return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - - } - - return null; - } - - private Object decodeX1(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { - - if (type == MSG_X1_GPS) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedInt(); // data and alarm - - decodeGps(position, buf, false, deviceSession.getTimeZone()); - - buf.readUnsignedShort(); // terminal info - - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedByte(), - buf.readUnsignedShort(), buf.readUnsignedInt()))); - - long driverId = buf.readUnsignedInt(); - if (driverId > 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(driverId)); - } - - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - - return position; - - } else if (type == MSG_X1_PHOTO_INFO) { - - buf.skipBytes(6); // time - buf.readUnsignedByte(); // fix status - buf.readUnsignedInt(); // latitude - buf.readUnsignedInt(); // longitude - buf.readUnsignedByte(); // camera id - buf.readUnsignedByte(); // photo source - buf.readUnsignedByte(); // picture format - - ByteBuf photo = Unpooled.buffer(buf.readInt()); - int pictureId = buf.readInt(); - photos.put(pictureId, photo); - sendPhotoRequest(channel, pictureId); - - } - - return null; - } - - private Object decodeWifi(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - ByteBuf time = buf.readSlice(6); - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(time, 2)) - .setMonth(BcdUtil.readInteger(time, 2)) - .setDay(BcdUtil.readInteger(time, 2)) - .setHour(BcdUtil.readInteger(time, 2)) - .setMinute(BcdUtil.readInteger(time, 2)) - .setSecond(BcdUtil.readInteger(time, 2)); - getLastLocation(position, dateBuilder.getDate()); - - Network network = new Network(); - - int wifiCount = buf.getByte(2); - for (int i = 0; i < wifiCount; i++) { - String mac = String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - network.addWifiAccessPoint(WifiAccessPoint.from(mac, buf.readUnsignedByte())); - } - - int cellCount = buf.readUnsignedByte(); - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); - } - - position.setNetwork(network); - - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(0x7878); - response.writeByte(0); - response.writeByte(type); - response.writeBytes(time.resetReaderIndex()); - response.writeByte('\r'); - response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - - return position; - } - - private Object decodeBasicOther(Channel channel, ByteBuf buf, - DeviceSession deviceSession, int type, int dataLength) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI - || type == MSG_LBS_2 || type == MSG_WIFI_3) { - - boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3; - - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - - getLastLocation(position, dateBuilder.getDate()); - - int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); - Network network = new Network(); - for (int i = 0; i < 7; i++) { - int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); - int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); - int rssi = -buf.readUnsignedByte(); - if (lac > 0) { - network.addCellTower(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid, rssi)); - } - } - - buf.readUnsignedByte(); // time leads - - if (type != MSG_LBS_MULTIPLE && type != MSG_LBS_2) { - int wifiCount = buf.readUnsignedByte(); - for (int i = 0; i < wifiCount; i++) { - String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); - } - } - - position.setNetwork(network); - - } else if (type == MSG_STRING) { - - getLastLocation(position, null); - - int commandLength = buf.readUnsignedByte(); - - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set(Position.KEY_RESULT, - buf.readSlice(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } - - } else if (isSupported(type)) { - - if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); - } else { - getLastLocation(position, null); - } - - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } - - if (hasStatus(type)) { - decodeStatus(position, buf); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 2 + 6) { - int mask = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); - if (BitUtil.check(mask, 8 + 4)) { - int value = BitUtil.to(mask, 8 + 1); - if (BitUtil.check(mask, 8 + 1)) { - value = -value; - } - position.set(Position.PREFIX_TEMP + 1, value); - } else { - int value = BitUtil.to(mask, 8 + 2); - if (BitUtil.check(mask, 8 + 5)) { - position.set(Position.PREFIX_ADC + 1, value); - } else { - position.set(Position.PREFIX_ADC + 1, value * 0.1); - } - } - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - - if (type == MSG_GPS_LBS_2 && buf.readableBytes() == 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } - - } else { - - 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); - } - return null; - - } - - if (hasLanguage(type)) { - buf.readUnsignedShort(); - } - - if (type == MSG_GPS_LBS_STATUS_3 || type == MSG_FENCE_MULTI) { - position.set(Position.KEY_GEOFENCE, buf.readUnsignedByte()); - } - - sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); - - return position; - } - - private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedShort(); // length - int type = buf.readUnsignedByte(); - - if (type == MSG_STRING_INFO) { - - buf.readUnsignedInt(); // server flag - String data; - if (buf.readUnsignedByte() == 1) { - data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.US_ASCII); - } else { - data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); - } - - if (decodeLocationString(position, data) == null) { - getLastLocation(position, null); - position.set(Position.KEY_RESULT, data); - } - - return position; - - } else if (type == MSG_INFO) { - - int subType = buf.readUnsignedByte(); - - getLastLocation(position, null); - - if (subType == 0x00) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - return position; - } else if (subType == 0x05) { - int flags = buf.readUnsignedByte(); - position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); - position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); - return position; - } else if (subType == 0x0a) { - buf.skipBytes(8); // imei - buf.skipBytes(8); // imsi - position.set("iccid", ByteBufUtil.hexDump(buf.readSlice(8))); - return position; - } else if (subType == 0x0d) { - if (buf.getByte(buf.readerIndex()) != '!') { - buf.skipBytes(6); - } - return decodeFuelData(position, buf.toString( - buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); - } - - } else if (type == MSG_X1_PHOTO_DATA) { - - int pictureId = buf.readInt(); - - ByteBuf photo = photos.get(pictureId); - - buf.readUnsignedInt(); // offset - buf.readBytes(photo, buf.readUnsignedShort()); - - if (photo.writableBytes() > 0) { - sendPhotoRequest(channel, pictureId); - } else { - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set( - Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); - photos.remove(pictureId).release(); - } - - } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { - - if (!decodeGps(position, buf, true, deviceSession.getTimeZone())) { - getLastLocation(position, position.getDeviceTime()); - } - - if (decodeLbs(position, buf, true)) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } - - buf.skipBytes(buf.readUnsignedByte()); // additional cell towers - buf.skipBytes(buf.readUnsignedByte()); // wifi access point - - int status = buf.readUnsignedByte(); - position.set(Position.KEY_STATUS, status); - - if (type == MSG_AZ735_ALARM) { - switch (status) { - case 0xA0: - position.set(Position.KEY_ARMED, true); - break; - case 0xA1: - position.set(Position.KEY_ARMED, false); - break; - case 0xA2: - case 0xA3: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 0xA4: - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - break; - case 0xA5: - position.set(Position.KEY_ALARM, Position.ALARM_DOOR); - break; - default: - break; - } - } - - buf.skipBytes(buf.readUnsignedByte()); // reserved extension - - sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); - - return position; - - } else if (type == MSG_OBD) { - - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - - getLastLocation(position, dateBuilder.getDate()); - - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - - String data = buf.readCharSequence(buf.readableBytes() - 18, StandardCharsets.US_ASCII).toString(); - for (String pair : data.split(",")) { - String[] values = pair.split("="); - switch (Integer.parseInt(values[0].substring(0, 2), 16)) { - case 40: - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[1], 16) * 0.01); - break; - case 43: - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[1], 16) * 0.01); - break; - case 45: - position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[1], 16) * 0.01); - break; - case 53: - position.set(Position.KEY_OBD_SPEED, Integer.parseInt(values[1], 16) * 0.01); - break; - case 54: - position.set(Position.KEY_RPM, Integer.parseInt(values[1], 16) * 0.01); - break; - case 71: - position.set(Position.KEY_FUEL_USED, Integer.parseInt(values[1], 16) * 0.01); - break; - case 73: - position.set(Position.KEY_HOURS, Integer.parseInt(values[1], 16) * 0.01); - break; - case 74: - position.set(Position.KEY_VIN, values[1]); - break; - default: - break; - } - } - - return position; - - } - - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int header = buf.readShort(); - - if (header == 0x7878) { - return decodeBasic(channel, remoteAddress, buf); - } else if (header == 0x7979) { - return decodeExtended(channel, remoteAddress, buf); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/org/traccar/protocol/Gt06ProtocolEncoder.java deleted file mode 100644 index 05560229f..000000000 --- a/src/org/traccar/protocol/Gt06ProtocolEncoder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.Context; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class Gt06ProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(long deviceId, String content) { - - boolean language = Context.getIdentityManager().lookupAttributeBoolean(deviceId, "gt06.language", false, true); - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte(0x78); - buf.writeByte(0x78); - - buf.writeByte(1 + 1 + 4 + content.length() + 2 + 2 + (language ? 2 : 0)); // message length - - buf.writeByte(0x80); // message type - - buf.writeByte(4 + content.length()); // command length - buf.writeInt(0); - buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); // command - - if (language) { - buf.writeShort(2); // english language - } - - buf.writeShort(0); // message index - - buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.nioBuffer(2, buf.writerIndex() - 2))); - - buf.writeByte('\r'); - buf.writeByte('\n'); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "gt06.alternative", false, true); - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), alternative ? "DYD,123456#" : "Relay,1#"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), alternative ? "HFYD,123456#" : "Relay,0#"); - case Command.TYPE_CUSTOM: - return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Gt30Protocol.java b/src/org/traccar/protocol/Gt30Protocol.java deleted file mode 100644 index aa4ad20b1..000000000 --- a/src/org/traccar/protocol/Gt30Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Gt30Protocol extends BaseProtocol { - - public Gt30Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gt30ProtocolDecoder(Gt30Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/org/traccar/protocol/Gt30ProtocolDecoder.java deleted file mode 100644 index abf208a46..000000000 --- a/src/org/traccar/protocol/Gt30ProtocolDecoder.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class Gt30ProtocolDecoder extends BaseProtocolDecoder { - - public Gt30ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$$") - .number("x{4}") // length - .expression("(.{14})") // device id - .number("x{4}") // type - .expression("(.)?") // alarm - .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .expression("[^\\|]*") - .number("|(d+.d+)") // hdop - .number("|(-?d+)") // altitude - .number("x{4}") // checksum - .compile(); - - private String decodeAlarm(int value) { - switch (value) { - case 0x01: - case 0x02: - case 0x03: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x12: - return Position.ALARM_GEOFENCE; - default: - return null; - } - } - - @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().trim()); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (parser.hasNext()) { - position.set(Position.KEY_ALARM, decodeAlarm(parser.next().charAt(0))); - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - - position.setAltitude(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/H02FrameDecoder.java b/src/org/traccar/protocol/H02FrameDecoder.java deleted file mode 100644 index 583ad599f..000000000 --- a/src/org/traccar/protocol/H02FrameDecoder.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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. - * 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 H02FrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_SHORT = 32; - private static final int MESSAGE_LONG = 45; - - private int messageLength; - - public H02FrameDecoder(int messageLength) { - this.messageLength = messageLength; - } - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - char marker = (char) buf.getByte(buf.readerIndex()); - - while (marker != '*' && marker != '$' && marker != 'X' && buf.readableBytes() > 0) { - buf.skipBytes(1); - if (buf.readableBytes() > 0) { - marker = (char) buf.getByte(buf.readerIndex()); - } - } - - switch (marker) { - case '*': - - // Return text message - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); - if (index != -1) { - 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 - } - return result; - } - - break; - - case '$': - - if (messageLength == 0) { - if (buf.readableBytes() == MESSAGE_LONG) { - messageLength = MESSAGE_LONG; - } else { - messageLength = MESSAGE_SHORT; - } - } - - if (buf.readableBytes() >= messageLength) { - return buf.readRetainedSlice(messageLength); - } - - break; - - case 'X': - - if (buf.readableBytes() >= MESSAGE_SHORT) { - return buf.readRetainedSlice(MESSAGE_SHORT); - } - - break; - - default: - - return null; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/H02Protocol.java b/src/org/traccar/protocol/H02Protocol.java deleted file mode 100644 index 251beac5e..000000000 --- a/src/org/traccar/protocol/H02Protocol.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.Context; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class H02Protocol extends BaseProtocol { - - public H02Protocol() { - setSupportedDataCommands( - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_POSITION_PERIODIC - ); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - int messageLength = Context.getConfig().getInteger(getName() + ".messageLength"); - pipeline.addLast(new H02FrameDecoder(messageLength)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new H02ProtocolEncoder()); - pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new H02ProtocolEncoder()); - pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); - } - }); - } -} diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java deleted file mode 100644 index c4443a00b..000000000 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; -import java.util.regex.Pattern; - -public class H02ProtocolDecoder extends BaseProtocolDecoder { - - public H02ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static double readCoordinate(ByteBuf buf, boolean lon) { - - int degrees = BcdUtil.readInteger(buf, 2); - if (lon) { - degrees = degrees * 10 + (buf.getUnsignedByte(buf.readerIndex()) >> 4); - } - - double result = 0; - if (lon) { - result = buf.readUnsignedByte() & 0x0f; - } - - int length = 6; - if (lon) { - length = 5; - } - - result = result * 10 + BcdUtil.readInteger(buf, length) * 0.0001; - - result /= 60; - result += degrees; - - return result; - } - - private void processStatus(Position position, long status) { - - if (!BitUtil.check(status, 0)) { - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); - } else if (!BitUtil.check(status, 1) || !BitUtil.check(status, 18)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } else if (!BitUtil.check(status, 2)) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } else if (!BitUtil.check(status, 19)) { - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - } - - position.set(Position.KEY_IGNITION, BitUtil.check(status, 10)); - position.set(Position.KEY_STATUS, status); - - } - - private Integer decodeBattery(int value) { - switch (value) { - case 6: - return 100; - case 5: - return 80; - case 4: - return 60; - case 3: - return 20; - case 2: - return 10; - default: - return null; - } - } - - private Position decodeBinary(ByteBuf buf, Channel channel, SocketAddress remoteAddress) { - - Position position = new Position(getProtocolName()); - - boolean longId = buf.readableBytes() == 42; - - buf.readByte(); // marker - - String id; - if (longId) { - id = ByteBufUtil.hexDump(buf.readSlice(8)).substring(0, 15); - } else { - id = ByteBufUtil.hexDump(buf.readSlice(5)); - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setYear(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - double latitude = readCoordinate(buf, false); - position.set(Position.KEY_BATTERY_LEVEL, decodeBattery(buf.readUnsignedByte())); - double longitude = readCoordinate(buf, true); - - int flags = buf.readUnsignedByte() & 0x0f; - position.setValid((flags & 0x02) != 0); - if ((flags & 0x04) == 0) { - latitude = -latitude; - } - if ((flags & 0x08) == 0) { - longitude = -longitude; - } - - position.setLatitude(latitude); - position.setLongitude(longitude); - - position.setSpeed(BcdUtil.readInteger(buf, 3)); - position.setCourse((buf.readUnsignedByte() & 0x0f) * 100.0 + BcdUtil.readInteger(buf, 2)); - - processStatus(position, buf.readUnsignedInt()); - - return position; - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*") - .expression("..,") // manufacturer - .number("(d+)?,") // imei - .groupBegin() - .text("V4,") - .expression("(.*),") // response - .or() - .expression("(V[^,]*),") - .groupEnd() - .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) - .groupBegin() - .expression("([ABV])?,") // validity - .or() - .number("(d+),") // coding scheme - .groupEnd() - .groupBegin() - .number("-(d+)-(d+.d+),") // latitude - .or() - .number("(d+)(dd.d+),") // latitude - .groupEnd() - .expression("([NS]),") - .groupBegin() - .number("-(d+)-(d+.d+),") // longitude - .or() - .number("(d+)(dd.d+),") // longitude - .groupEnd() - .expression("([EW]),") - .number("(d+.?d*),") // speed - .number("(d+.?d*)?,") // course - .number("(?:d+,)?") // battery - .number("(?:(dd)(dd)(dd))?") // date (ddmmyy) - .groupBegin() - .expression(",[^,]*,") - .expression("[^,]*,") - .expression("[^,]*") // sim info - .groupEnd("?") - .groupBegin() - .number(",(x{8})") - .groupBegin() - .number(",(d+),") // odometer - .number("(-?d+),") // temperature - .number("(d+.d+),") // fuel - .number("(-?d+),") // altitude - .number("(x+),") // lac - .number("(x+)") // cid - .or() - .text(",") - .expression("(.*)") // data - .or() - .groupEnd() - .or() - .groupEnd() - .text("#") - .compile(); - - private static final Pattern PATTERN_NBR = new PatternBuilder() - .text("*") - .expression("..,") // manufacturer - .number("(d+),") // imei - .text("NBR,") - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("d+,") // gsm delay time - .number("d+,") // count - .number("((?:d+,d+,d+,)+)") // cells - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(x{8})") // status - .any() - .compile(); - - private static final Pattern PATTERN_LINK = new PatternBuilder() - .text("*") - .expression("..,") // manufacturer - .number("(d+),") // imei - .text("LINK,") - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+),") // rssi - .number("(d+),") // satellites - .number("(d+),") // battery - .number("(d+),") // steps - .number("(d+),") // turnovers - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(x{8})") // status - .any() - .compile(); - - private static final Pattern PATTERN_V3 = new PatternBuilder() - .text("*") - .expression("..,") // manufacturer - .number("(d+),") // imei - .text("V3,") - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(ddd)") // mcc - .number("(d+),") // mnc - .number("(d+),") // count - .expression("(.*),") // cell info - .number("(x{4}),") // battery - .number("d+,") // reboot info - .text("X,") - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(x{8})") // status - .text("#").optional() - .compile(); - - private static final Pattern PATTERN_VP1 = new PatternBuilder() - .text("*hq,") - .number("(d{15}),") // imei - .text("VP1,") - .groupBegin() - .text("V,") - .number("(d+),") // mcc - .number("(d+),") // mnc - .expression("([^#]+)") // cells - .or() - .expression("[AB],") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+),") // speed - .number("(d+.d+),") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .groupEnd() - .any() - .compile(); - - private void sendResponse(Channel channel, SocketAddress remoteAddress, String id, String type) { - if (channel != null && id != null) { - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - String response = String.format("*HQ,%s,V4,%s,%s#", id, type, dateFormat.format(new Date())); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - private Position decodeText(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN, 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()); - - if (parser.hasNext()) { - position.set(Position.KEY_RESULT, parser.next()); - } - - if (parser.hasNext() && parser.next().equals("V1")) { - sendResponse(channel, remoteAddress, id, "V1"); - } - - DateBuilder dateBuilder = new DateBuilder(); - if (parser.hasNext(3)) { - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - } - - if (parser.hasNext()) { - position.setValid(parser.next().equals("A")); - } - if (parser.hasNext()) { - parser.nextInt(); // coding scheme - position.setValid(true); - } - - if (parser.hasNext(2)) { - position.setLatitude(-parser.nextCoordinate()); - } - if (parser.hasNext(2)) { - position.setLatitude(parser.nextCoordinate()); - } - - if (parser.hasNext(2)) { - position.setLongitude(-parser.nextCoordinate()); - } - if (parser.hasNext(2)) { - position.setLongitude(parser.nextCoordinate()); - } - - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext(3)) { - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - } else { - position.setTime(new Date()); - } - - if (parser.hasNext()) { - processStatus(position, parser.nextLong(16, 0)); - } - - if (parser.hasNext(6)) { - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); - - position.setAltitude(parser.nextInt(0)); - - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); - } - - if (parser.hasNext(4)) { - String[] values = parser.next().split(","); - for (int i = 0; i < values.length; i++) { - position.set(Position.PREFIX_IO + (i + 1), values[i].trim()); - } - } - - return position; - } - - private Position decodeLbs(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_NBR, sentence); - if (!parser.matches()) { - return null; - } - - String id = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - sendResponse(channel, remoteAddress, id, "NBR"); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - Network network = new Network(); - int mcc = parser.nextInt(0); - int mnc = parser.nextInt(0); - - String[] cells = parser.next().split(","); - for (int i = 0; i < cells.length / 3; i++) { - network.addCellTower(CellTower.from(mcc, mnc, Integer.parseInt(cells[i * 3]), - Integer.parseInt(cells[i * 3 + 1]), Integer.parseInt(cells[i * 3 + 2]))); - } - - position.setNetwork(network); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - getLastLocation(position, dateBuilder.getDate()); - - processStatus(position, parser.nextLong(16, 0)); - - return position; - } - - private Position decodeLink(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_LINK, 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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_STEPS, parser.nextInt()); - position.set("turnovers", parser.nextInt()); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - getLastLocation(position, dateBuilder.getDate()); - - processStatus(position, parser.nextLong(16, 0)); - - return position; - } - - private Position decodeV3(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_V3, 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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - - int count = parser.nextInt(); - Network network = new Network(); - String[] values = parser.next().split(","); - for (int i = 0; i < count; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, Integer.parseInt(values[i * 4]), Integer.parseInt(values[i * 4 + 1]))); - } - position.setNetwork(network); - - position.set(Position.KEY_BATTERY, parser.nextHexInt()); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - getLastLocation(position, dateBuilder.getDate()); - - processStatus(position, parser.nextLong(16, 0)); - - return position; - } - - private Position decodeVp1(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_VP1, 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()); - - if (parser.hasNext(3)) { - - getLastLocation(position, null); - - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - - Network network = new Network(); - for (String cell : parser.next().split("Y")) { - String[] values = cell.split(","); - network.addCellTower(CellTower.from(mcc, mnc, - Integer.parseInt(values[0]), Integer.parseInt(values[1]), Integer.parseInt(values[2]))); - } - - position.setNetwork(network); - - } else { - - position.setValid(true); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - position.setTime(new DateBuilder() - .setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)).getDate()); - - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - String marker = buf.toString(0, 1, StandardCharsets.US_ASCII); - - switch (marker) { - case "*": - String sentence = buf.toString(StandardCharsets.US_ASCII).trim(); - int typeStart = sentence.indexOf(',', sentence.indexOf(',') + 1) + 1; - int typeEnd = sentence.indexOf(',', typeStart); - if (typeEnd > 0) { - String type = sentence.substring(typeStart, typeEnd); - switch (type) { - case "NBR": - return decodeLbs(sentence, channel, remoteAddress); - case "LINK": - return decodeLink(sentence, channel, remoteAddress); - case "V3": - return decodeV3(sentence, channel, remoteAddress); - case "VP1": - return decodeVp1(sentence, channel, remoteAddress); - default: - return decodeText(sentence, channel, remoteAddress); - } - } else { - return null; - } - case "$": - return decodeBinary(buf, channel, remoteAddress); - case "X": - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/H02ProtocolEncoder.java b/src/org/traccar/protocol/H02ProtocolEncoder.java deleted file mode 100644 index 614a07dd1..000000000 --- a/src/org/traccar/protocol/H02ProtocolEncoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) - * 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. - * 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.Context; -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -import java.util.Date; - -public class H02ProtocolEncoder extends StringProtocolEncoder { - - private static final String MARKER = "HQ"; - - private Object formatCommand(Date time, String uniqueId, String type, String... params) { - - StringBuilder result = new StringBuilder( - String.format("*%s,%s,%s,%4$tH%4$tM%4$tS", MARKER, uniqueId, type, time)); - - for (String param : params) { - result.append(",").append(param); - } - - result.append("#"); - - return result.toString(); - } - - protected Object encodeCommand(Command command, Date time) { - String uniqueId = getUniqueId(command.getDeviceId()); - - switch (command.getType()) { - case Command.TYPE_ALARM_ARM: - return formatCommand(time, uniqueId, "SCF", "0", "0"); - case Command.TYPE_ALARM_DISARM: - return formatCommand(time, uniqueId, "SCF", "1", "1"); - case Command.TYPE_ENGINE_STOP: - return formatCommand(time, uniqueId, "S20", "1", "1"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(time, uniqueId, "S20", "1", "0"); - case Command.TYPE_POSITION_PERIODIC: - String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "h02.alternative", false, true)) { - return formatCommand(time, uniqueId, "D1", frequency); - } else { - return formatCommand(time, uniqueId, "S71", "22", frequency); - } - default: - return null; - } - } - - @Override - protected Object encodeCommand(Command command) { - return encodeCommand(command, new Date()); - } - -} diff --git a/src/org/traccar/protocol/HaicomProtocol.java b/src/org/traccar/protocol/HaicomProtocol.java deleted file mode 100644 index 6e5760bd4..000000000 --- a/src/org/traccar/protocol/HaicomProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class HaicomProtocol extends BaseProtocol { - - public HaicomProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new HaicomProtocolDecoder(HaicomProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/HaicomProtocolDecoder.java b/src/org/traccar/protocol/HaicomProtocolDecoder.java deleted file mode 100644 index dd20f2aeb..000000000 --- a/src/org/traccar/protocol/HaicomProtocolDecoder.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class HaicomProtocolDecoder extends BaseProtocolDecoder { - - public HaicomProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$GPRS") - .number("(d+),") // imei - .expression("([^,]+),") // version - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d)") // flags - .number("(dd)(d{5})") // latitude - .number("(ddd)(d{5}),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // status - .number("(d+)?,") // gprs counting value - .number("(d+)?,") // gps power saving counting value - .number("(d+),") // switch status - .number("(d+)") // relay status - .expression("(?:[LH]{2})?") // power status - .number("#V(d+)") // battery - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_FW, parser.next()); - - position.setTime(parser.nextDateTime()); - - int flags = parser.nextInt(0); - - position.setValid(BitUtil.check(flags, 0)); - - double latitude = parser.nextDouble(0) + parser.nextDouble(0) / 60000; - if (BitUtil.check(flags, 2)) { - position.setLatitude(latitude); - } else { - position.setLatitude(-latitude); - } - - double longitude = parser.nextDouble(0) + parser.nextDouble(0) / 60000; - if (BitUtil.check(flags, 1)) { - position.setLongitude(longitude); - } else { - position.setLongitude(-longitude); - } - - position.setSpeed(parser.nextDouble(0) / 10); - position.setCourse(parser.nextDouble(0) / 10); - - position.set(Position.KEY_STATUS, parser.next()); - position.set("gprsCount", parser.next()); - position.set("powersaveCountdown", parser.next()); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - position.set(Position.KEY_BATTERY, parser.nextDouble(0) * 0.1); - - return position; - } - -} diff --git a/src/org/traccar/protocol/HomtecsProtocol.java b/src/org/traccar/protocol/HomtecsProtocol.java deleted file mode 100644 index 34dbf0f51..000000000 --- a/src/org/traccar/protocol/HomtecsProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class HomtecsProtocol extends BaseProtocol { - - public HomtecsProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new HomtecsProtocolDecoder(HomtecsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/org/traccar/protocol/HomtecsProtocolDecoder.java deleted file mode 100644 index a93572b5c..000000000 --- a/src/org/traccar/protocol/HomtecsProtocolDecoder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class HomtecsProtocolDecoder extends BaseProtocolDecoder { - - public HomtecsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("([^_]+)") // id - .text("_R") - .number("(x{8}),") // mac ending - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd).d+,") // time (hhmmss) - .number("(d+),") // satellites - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(d),") // fix status - .number("(d+.?d*)?,") // hdop - .number("(d+.?d*)?") // altitude - .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; - } - - String id = parser.next(); - String mac = parser.next(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id, id + "_R" + mac); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.setValid(parser.nextInt(0) > 0); - - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - - position.setAltitude(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/HuaShengFrameDecoder.java b/src/org/traccar/protocol/HuaShengFrameDecoder.java deleted file mode 100644 index bd52aa9e7..000000000 --- a/src/org/traccar/protocol/HuaShengFrameDecoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class HuaShengFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 2) { - return null; - } - - int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0xC0); - if (index != -1) { - ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); - - while (buf.readerIndex() <= index) { - int b = buf.readUnsignedByte(); - if (b == 0xDB) { - int ext = buf.readUnsignedByte(); - if (ext == 0xDC) { - result.writeByte(0xC0); - } else if (ext == 0xDD) { - result.writeByte(0xDB); - } - } else { - result.writeByte(b); - } - } - - return result; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/HuaShengProtocol.java b/src/org/traccar/protocol/HuaShengProtocol.java deleted file mode 100644 index 103f2d501..000000000 --- a/src/org/traccar/protocol/HuaShengProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class HuaShengProtocol extends BaseProtocol { - - public HuaShengProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HuaShengFrameDecoder()); - pipeline.addLast(new HuaShengProtocolDecoder(HuaShengProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/org/traccar/protocol/HuaShengProtocolDecoder.java deleted file mode 100644 index 8a937a194..000000000 --- a/src/org/traccar/protocol/HuaShengProtocolDecoder.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.charset.StandardCharsets; - -public class HuaShengProtocolDecoder extends BaseProtocolDecoder { - - public HuaShengProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_POSITION = 0xAA00; - public static final int MSG_POSITION_RSP = 0xFF01; - public static final int MSG_LOGIN = 0xAA02; - public static final int MSG_LOGIN_RSP = 0xFF03; - 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, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(0xC0); - response.writeShort(0x0100); - response.writeShort(12 + (content != null ? content.readableBytes() : 0)); - response.writeShort(type); - response.writeShort(0); - response.writeInt(index); - if (content != null) { - response.writeBytes(content); - content.release(); - } - response.writeByte(0xC0); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(1); // start marker - buf.readUnsignedByte(); // flag - buf.readUnsignedByte(); // reserved - buf.readUnsignedShort(); // length - - int type = buf.readUnsignedShort(); - - buf.readUnsignedShort(); // checksum - int index = buf.readInt(); - - if (type == MSG_LOGIN) { - - while (buf.readableBytes() > 4) { - int subtype = buf.readUnsignedShort(); - int length = buf.readUnsignedShort() - 4; - if (subtype == 0x0003) { - String imei = buf.readSlice(length).toString(StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && channel != null) { - ByteBuf content = Unpooled.buffer(); - content.writeByte(0); // success - sendResponse(channel, MSG_LOGIN_RSP, index, content); - } - } else { - buf.skipBytes(length); - } - } - - } else if (type == MSG_HSO_REQ) { - - sendResponse(channel, MSG_HSO_RSP, index, null); - - } else if (type == MSG_POSITION) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int status = buf.readUnsignedShort(); - - position.setValid(BitUtil.check(status, 15)); - - position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 14)); - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - - String time = buf.readSlice(12).toString(StandardCharsets.US_ASCII); - - DateBuilder dateBuilder = new DateBuilder() - .setYear(Integer.parseInt(time.substring(0, 2))) - .setMonth(Integer.parseInt(time.substring(2, 4))) - .setDay(Integer.parseInt(time.substring(4, 6))) - .setHour(Integer.parseInt(time.substring(6, 8))) - .setMinute(Integer.parseInt(time.substring(8, 10))) - .setSecond(Integer.parseInt(time.substring(10, 12))); - position.setTime(dateBuilder.getDate()); - - position.setLongitude(buf.readInt() * 0.00001); - position.setLatitude(buf.readInt() * 0.00001); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readUnsignedShort()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000); - - while (buf.readableBytes() > 4) { - buf.readUnsignedShort(); // subtype - int length = buf.readUnsignedShort() - 4; - buf.skipBytes(length); - } - - sendResponse(channel, MSG_POSITION_RSP, index, null); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/HuabaoFrameDecoder.java b/src/org/traccar/protocol/HuabaoFrameDecoder.java deleted file mode 100644 index b520f6be9..000000000 --- a/src/org/traccar/protocol/HuabaoFrameDecoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class HuabaoFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 2) { - return null; - } - - int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0x7e); - if (index != -1) { - ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); - - while (buf.readerIndex() <= index) { - int b = buf.readUnsignedByte(); - if (b == 0x7d) { - int ext = buf.readUnsignedByte(); - if (ext == 0x01) { - result.writeByte(0x7d); - } else if (ext == 0x02) { - result.writeByte(0x7e); - } - } else { - result.writeByte(b); - } - } - - return result; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/HuabaoProtocol.java b/src/org/traccar/protocol/HuabaoProtocol.java deleted file mode 100644 index 44c9f7ac7..000000000 --- a/src/org/traccar/protocol/HuabaoProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class HuabaoProtocol extends BaseProtocol { - - public HuabaoProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HuabaoFrameDecoder()); - pipeline.addLast(new HuabaoProtocolEncoder()); - pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/org/traccar/protocol/HuabaoProtocolDecoder.java deleted file mode 100644 index 6e2e1377b..000000000 --- a/src/org/traccar/protocol/HuabaoProtocolDecoder.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; - -public class HuabaoProtocolDecoder extends BaseProtocolDecoder { - - public HuabaoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_GENERAL_RESPONSE = 0x8001; - public static final int MSG_TERMINAL_REGISTER = 0x0100; - public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100; - public static final int MSG_TERMINAL_CONTROL = 0x8105; - 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 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); - data.release(); - buf.writeByte(Checksum.xor(buf.nioBuffer(1, buf.readableBytes() - 1))); - buf.writeByte(0x7e); - return buf; - } - - private void sendGeneralResponse( - Channel channel, SocketAddress remoteAddress, ByteBuf id, int type, int index) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(index); - response.writeShort(type); - response.writeByte(RESULT_SUCCESS); - channel.writeAndFlush(new NetworkMessage( - formatMessage(MSG_GENERAL_RESPONSE, id, response), remoteAddress)); - } - } - - private String decodeAlarm(long value) { - if (BitUtil.check(value, 0)) { - return Position.ALARM_SOS; - } - if (BitUtil.check(value, 1)) { - return Position.ALARM_OVERSPEED; - } - if (BitUtil.check(value, 5)) { - return Position.ALARM_GPS_ANTENNA_CUT; - } - if (BitUtil.check(value, 4) || BitUtil.check(value, 9) - || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { - return Position.ALARM_FAULT; - } - if (BitUtil.check(value, 8)) { - return Position.ALARM_POWER_OFF; - } - if (BitUtil.check(value, 20)) { - return Position.ALARM_GEOFENCE; - } - if (BitUtil.check(value, 29)) { - return Position.ALARM_ACCIDENT; - } - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // start marker - int type = buf.readUnsignedShort(); - buf.readUnsignedShort(); // body length - ByteBuf id = buf.readSlice(6); // phone number - int index = buf.readUnsignedShort(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); - if (deviceSession == null) { - return null; - } - - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId(), "GMT+8")); - } - - if (type == MSG_TERMINAL_REGISTER) { - - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(index); - response.writeByte(RESULT_SUCCESS); - response.writeBytes("authentication".getBytes(StandardCharsets.US_ASCII)); - channel.writeAndFlush(new NetworkMessage( - formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, response), remoteAddress)); - } - - } else if (type == MSG_TERMINAL_AUTH) { - - sendGeneralResponse(channel, remoteAddress, id, type, index); - - } else if (type == MSG_LOCATION_REPORT) { - - return decodeLocation(deviceSession, buf); - - } else if (type == MSG_LOCATION_BATCH) { - - return decodeLocationBatch(deviceSession, buf); - - } - - return null; - } - - private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); - - int flags = buf.readInt(); - - position.set(Position.KEY_IGNITION, BitUtil.check(flags, 0)); - - position.setValid(BitUtil.check(flags, 1)); - - double lat = buf.readUnsignedInt() * 0.000001; - double lon = buf.readUnsignedInt() * 0.000001; - - if (BitUtil.check(flags, 2)) { - position.setLatitude(-lat); - } else { - position.setLatitude(lat); - } - - 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(deviceSession.getTimeZone()) - .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()); - - while (buf.readableBytes() > 2) { - int subtype = buf.readUnsignedByte(); - int length = buf.readUnsignedByte(); - switch (subtype) { - case 0x01: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); - break; - case 0x30: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 0x31: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - default: - buf.skipBytes(length); - break; - } - } - - 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 deleted file mode 100644 index 7759790c4..000000000 --- a/src/org/traccar/protocol/HuabaoProtocolEncoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@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 org.traccar.BaseProtocolEncoder; -import org.traccar.Context; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.text.SimpleDateFormat; -import java.util.Date; - -public class HuabaoProtocolEncoder extends BaseProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "huabao.alternative", false, true); - - ByteBuf id = Unpooled.wrappedBuffer( - DataConverter.parseHex(getUniqueId(command.getDeviceId()))); - try { - ByteBuf data = Unpooled.buffer(); - byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - if (alternative) { - data.writeByte(0x01); - data.writeBytes(time); - return HuabaoProtocolDecoder.formatMessage( - HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); - } else { - data.writeByte(0xf0); - return HuabaoProtocolDecoder.formatMessage( - HuabaoProtocolDecoder.MSG_TERMINAL_CONTROL, id, data); - } - case Command.TYPE_ENGINE_RESUME: - if (alternative) { - data.writeByte(0x00); - data.writeBytes(time); - return HuabaoProtocolDecoder.formatMessage( - HuabaoProtocolDecoder.MSG_OIL_CONTROL, id, data); - } else { - data.writeByte(0xf1); - return HuabaoProtocolDecoder.formatMessage( - HuabaoProtocolDecoder.MSG_TERMINAL_CONTROL, id, data); - } - default: - return null; - } - } finally { - id.release(); - } - } - -} diff --git a/src/org/traccar/protocol/HunterProProtocol.java b/src/org/traccar/protocol/HunterProProtocol.java deleted file mode 100644 index 9f6424a57..000000000 --- a/src/org/traccar/protocol/HunterProProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class HunterProProtocol extends BaseProtocol { - - public HunterProProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new HunterProProtocolDecoder(HunterProProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/HunterProProtocolDecoder.java b/src/org/traccar/protocol/HunterProProtocolDecoder.java deleted file mode 100644 index 06bc12d59..000000000 --- a/src/org/traccar/protocol/HunterProProtocolDecoder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class HunterProProtocolDecoder extends BaseProtocolDecoder { - - public HunterProProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number(">(d+)<") // identifier - .text("$GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder(); - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/IdplProtocol.java b/src/org/traccar/protocol/IdplProtocol.java deleted file mode 100644 index 418178756..000000000 --- a/src/org/traccar/protocol/IdplProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class IdplProtocol extends BaseProtocol { - - public IdplProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new IdplProtocolDecoder(IdplProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/IdplProtocolDecoder.java b/src/org/traccar/protocol/IdplProtocolDecoder.java deleted file mode 100644 index cf3c03d7f..000000000 --- a/src/org/traccar/protocol/IdplProtocolDecoder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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. - * 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 java.net.SocketAddress; -import java.util.regex.Pattern; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.Parser.CoordinateFormat; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -public class IdplProtocolDecoder extends BaseProtocolDecoder { - - public IdplProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*ID") // start of frame - .number("(d+),") // command code - .number("(d+),") // imei - .number("(dd)(dd)(dd),") // current date (ddmmyy) - .number("(dd)(dd)(dd),") // current time (hhmmss) - .expression("([A|V]),") // gps fix - .number("(dd)(dd).?(d+),([NS]),") // latitude - .number("(ddd)(dd).?(d+),([EW]),") // longitude - .number("(d{1,3}.dd),") // speed - .number("(d{1,3}.dd),") // course - .number("(d{1,2}),") // sats - .number("(d{1,3}),") // gsm signal strength - .expression("([A|N|S]),") // vehicle status - .expression("([0|1]),") // main power status - .number("(d.dd),") // internal battery voltage - .expression("([0|1]),") // sos alert - .expression("([0|1]),") // body tamper - .expression("([0|1])([0|1]),") // ac status + ign status - .expression("([0|1|2]),") // output1 status - .number("(d{1,3}),") // adc1 - .number("(d{1,3}),") // adc2 - .expression("([0-9A-Z]{3}),") // software version - .expression("([L|R]),") // message type - .number("(x{4})#") // crc - .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; - } - - Position position = new Position(getProtocolName()); - - position.set(Position.KEY_TYPE, parser.nextInt(0)); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set("vehicleStatus", parser.next()); - position.set(Position.KEY_POWER, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - if (parser.nextInt(0) == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - parser.nextInt(0); // body tamper - position.set("acStatus", parser.nextInt(0)); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - position.set(Position.KEY_OUTPUT, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 2, parser.nextInt(0)); - position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_ARCHIVE, parser.next().equals("R")); - - parser.next(); // checksum - - return position; - } - -} diff --git a/src/org/traccar/protocol/IntellitracFrameDecoder.java b/src/org/traccar/protocol/IntellitracFrameDecoder.java deleted file mode 100644 index 8322e65ba..000000000 --- a/src/org/traccar/protocol/IntellitracFrameDecoder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - * 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.ChannelHandlerContext; -import io.netty.handler.codec.LineBasedFrameDecoder; -import org.traccar.NetworkMessage; - -public class IntellitracFrameDecoder extends LineBasedFrameDecoder { - - private static final int MESSAGE_MINIMUM_LENGTH = 0; - - public IntellitracFrameDecoder(int maxFrameLength) { - super(maxFrameLength); - } - - // example of sync header: 0xFA 0xF8 0x1B 0x01 0x81 0x60 0x33 0x3C - - @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { - - // Check minimum length - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - // Check for sync packet - if (buf.getUnsignedShort(buf.readerIndex()) == 0xFAF8) { - ByteBuf syncMessage = buf.readRetainedSlice(8); - if (ctx != null && ctx.channel() != null) { - ctx.channel().writeAndFlush(new NetworkMessage(syncMessage, ctx.channel().remoteAddress())); - } - } - - return super.decode(ctx, buf); - } - -} diff --git a/src/org/traccar/protocol/IntellitracProtocol.java b/src/org/traccar/protocol/IntellitracProtocol.java deleted file mode 100644 index 3abf40da7..000000000 --- a/src/org/traccar/protocol/IntellitracProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class IntellitracProtocol extends BaseProtocol { - - public IntellitracProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new IntellitracFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new IntellitracProtocolDecoder(IntellitracProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/org/traccar/protocol/IntellitracProtocolDecoder.java deleted file mode 100644 index 897606270..000000000 --- a/src/org/traccar/protocol/IntellitracProtocolDecoder.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 IntellitracProtocolDecoder extends BaseProtocolDecoder { - - public IntellitracProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression(".+,").optional() - .number("(d+),") // identifier - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // longitude - .number("(-?d+.d+),") // latitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(-?d+.?d*),") // altitude - .number("(d+),") // satellites - .number("(d+),") // index - .number("(d+),") // input - .number("(d+),?") // output - .number("(d+.d+)?,?") // adc1 - .number("(d+.d+)?,?") // adc2 - .groupBegin() - .number("d{14},d+,") - .number("(d+),") // vss - .number("(d+),") // rpm - .number("(-?d+),") // coolant - .number("(d+),") // fuel - .number("(d+),") // fuel consumption - .number("(-?d+),") // fuel temperature - .number("(d+),") // charger pressure - .number("(d+),") // tpl - .number("(d+),") // axle weight - .number("(d+)") // odometer - .groupEnd("?") - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setValid(true); - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_INDEX, parser.nextLong()); - position.set(Position.KEY_INPUT, parser.nextInt()); - position.set(Position.KEY_OUTPUT, parser.nextInt()); - - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); - - // J1939 data - position.set(Position.KEY_OBD_SPEED, parser.nextInt()); - position.set(Position.KEY_RPM, parser.nextInt()); - position.set("coolant", parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set("chargerPressure", parser.nextInt()); - position.set("tpl", parser.nextInt()); - position.set(Position.KEY_AXLE_WEIGHT, parser.nextInt()); - position.set(Position.KEY_OBD_ODOMETER, parser.nextInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ItsProtocol.java b/src/org/traccar/protocol/ItsProtocol.java deleted file mode 100644 index f53600dc9..000000000 --- a/src/org/traccar/protocol/ItsProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class ItsProtocol extends BaseProtocol { - - public ItsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new ItsProtocolDecoder(ItsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ItsProtocolDecoder.java b/src/org/traccar/protocol/ItsProtocolDecoder.java deleted file mode 100644 index 482f34e65..000000000 --- a/src/org/traccar/protocol/ItsProtocolDecoder.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2018 - 2019 Anton Tananaev (anton@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.Protocol; -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 ItsProtocolDecoder extends BaseProtocolDecoder { - - public ItsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("[^$]*") - .text("$") - .expression(",?[^,]+,") // event - .groupBegin() - .expression("[^,]+,") // vendor - .expression("[^,]+,") // firmware version - .expression("[^,]+,") // type - .number("d+,") - .expression("[LH],") // history - .or() - .expression("[^,]+,") // type - .groupEnd() - .number("(d{15}),") // imei - .groupBegin() - .expression("(..),") // status - .or() - .expression("[^,]*,") // vehicle registration - .number("([01]),") // valid - .groupEnd() - .number("(dd),?(dd),?(dddd),") // date (ddmmyyyy) - .number("(dd),?(dd),?(dd),") // time (hhmmss) - .expression("([AV]),").optional() // valid - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .groupBegin() - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+),") // satellites - .groupBegin() - .number("(d+.?d*),") // altitude - .number("d+.?d*,") // pdop - .number("d+.?d*,") // hdop - .expression("[^,]*,") - .number("([01]),") // ignition - .number("([01]),") // charging - .number("(d+.?d*),") // power - .number("(d+.?d*),") // battery - .number("[01],") // emergency - .expression("[CO]?,") // tamper - .number("(?:x+,){5}") // main cell - .number("(?:-?x+,){12}") // other cells - .number("([01]{4}),") // inputs - .number("([01]{2}),") // outputs - .groupEnd("?") - .or() - .number("(-?d+.d+),") // altitude - .number("(d+.d+),") // speed - .groupEnd() - .any() - .compile(); - - private String decodeAlarm(String status) { - switch (status) { - case "WD": - case "EA": - return Position.ALARM_SOS; - case "BL": - return Position.ALARM_LOW_BATTERY; - case "HB": - return Position.ALARM_BRAKING; - case "HA": - return Position.ALARM_ACCELERATION; - case "RT": - return Position.ALARM_CORNERING; - case "OS": - return Position.ALARM_OVERSPEED; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (channel != null && sentence.startsWith("$,01,")) { - channel.writeAndFlush(new NetworkMessage("$,1,*", remoteAddress)); - } - - 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()); - - if (parser.hasNext()) { - position.set(Position.KEY_ALARM, decodeAlarm(parser.next())); - } - - if (parser.hasNext()) { - position.setValid(parser.nextInt() == 1); - } - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - if (parser.hasNext()) { - position.setValid(parser.next().equals("A")); - } - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - - if (parser.hasNext(3)) { - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - } - - if (parser.hasNext(7)) { - position.setAltitude(parser.nextDouble()); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); - position.set(Position.KEY_CHARGE, parser.nextInt() > 0); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_INPUT, parser.nextBinInt()); - position.set(Position.KEY_OUTPUT, parser.nextBinInt()); - } - - if (parser.hasNext(2)) { - position.setAltitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/Ivt401Protocol.java b/src/org/traccar/protocol/Ivt401Protocol.java deleted file mode 100644 index fb44e4fe9..000000000 --- a/src/org/traccar/protocol/Ivt401Protocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.CharacterDelimiterFrameDecoder; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class Ivt401Protocol extends BaseProtocol { - - public Ivt401Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Ivt401ProtocolDecoder(Ivt401Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java deleted file mode 100644 index 63556e7a9..000000000 --- a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 Ivt401ProtocolDecoder extends BaseProtocolDecoder { - - public Ivt401ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .expression("TL[ABLN],") // header - .number("(d+),") // imei - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("([-+]d+.d+),") // latitude - .number("([-+]d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(-?d+.?d*),") // altitude - .number("d+,") // satellites or battery status - .number("(d),") // gps status - .number("(d+),") // rssi - .number("(d+),") // input - .number("(d+),") // output - .number("(d+.d+),") // adc - .number("(d+.d+),") // power - .number("(d+.d+),") // battery - .number("(-?d+.?d*),") // pcb temp - .expression("([^,]+),") // temp - .number("(d+),") // movement - .number("(d+.d+),") // acceleration - .number("(-?d+),") // tilt - .number("(d+),") // trip - .number("(d+),") // odometer - .groupBegin() - .number("([01]),") // overspeed - .number("[01],") // input 2 misuse - .number("[01],") // immobilizer - .number("[01],") // temperature alert - .number("[0-2]+,") // geofence - .number("([0-3]),") // harsh driving - .number("[01],") // reconnect - .number("([01]),") // low battery - .number("([01]),") // power disconnected - .number("[01],") // gps failure - .number("([01]),") // towing - .number("[01],") // server unreachable - .number("[128],") // sleep mode - .expression("([^,]+)?,") // driver id - .number("d+,") // sms count - .groupEnd("?") - .any() - .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.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); - position.setCourse(parser.nextInt()); - position.setAltitude(parser.nextDouble()); - position.setValid(parser.nextInt() > 0); - - position.set(Position.KEY_RSSI, parser.nextInt()); - - String input = parser.next(); - for (int i = 0; i < input.length(); i++) { - int value = Character.getNumericValue(input.charAt(i)); - if (value < 2) { - position.set(Position.PREFIX_IN + (i + 1), value > 0); - } - } - - String output = parser.next(); - for (int i = 0; i < output.length(); i++) { - position.set(Position.PREFIX_OUT + (i + 1), Character.getNumericValue(output.charAt(i)) > 0); - } - - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_DEVICE_TEMP, parser.nextDouble()); - - String temp = parser.next(); - if (temp.startsWith("M")) { - int index = 1; - int startIndex = 1; - int endIndex; - while (startIndex < temp.length()) { - endIndex = temp.indexOf('-', startIndex + 1); - if (endIndex < 0) { - endIndex = temp.indexOf('+', startIndex + 1); - } - if (endIndex < 0) { - endIndex = temp.length(); - } - if (endIndex > 0) { - double value = Double.parseDouble(temp.substring(startIndex, endIndex)); - position.set(Position.PREFIX_TEMP + index++, value); - } - startIndex = endIndex; - } - } else { - position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(temp)); - } - - position.set(Position.KEY_MOTION, parser.nextInt() > 0); - position.set(Position.KEY_ACCELERATION, parser.nextDouble()); - - parser.nextInt(); // tilt - parser.nextInt(); // trip state - - position.set(Position.KEY_ODOMETER, parser.nextLong()); - - if (parser.hasNext(6)) { - position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_OVERSPEED : null); - switch (parser.nextInt()) { - 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; - } - position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_LOW_BATTERY : null); - position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_POWER_CUT : null); - position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_TOW : null); - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/JpKorjarFrameDecoder.java b/src/org/traccar/protocol/JpKorjarFrameDecoder.java deleted file mode 100644 index 0eb65c8ef..000000000 --- a/src/org/traccar/protocol/JpKorjarFrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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 JpKorjarFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 80) { - return null; - } - - int spaceIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ' '); - if (spaceIndex == -1) { - return null; - } - - int endIndex = buf.indexOf(spaceIndex, buf.writerIndex(), (byte) ','); - if (endIndex == -1) { - return null; - } - - return buf.readRetainedSlice(endIndex + 1); - } - -} diff --git a/src/org/traccar/protocol/JpKorjarProtocol.java b/src/org/traccar/protocol/JpKorjarProtocol.java deleted file mode 100644 index fe5b2480d..000000000 --- a/src/org/traccar/protocol/JpKorjarProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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; - -public class JpKorjarProtocol extends BaseProtocol { - - public JpKorjarProtocol() { - addServer(new TrackerServer(false, this.getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new JpKorjarFrameDecoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new JpKorjarProtocolDecoder(JpKorjarProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/org/traccar/protocol/JpKorjarProtocolDecoder.java deleted file mode 100644 index a8389d1b1..000000000 --- a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java +++ /dev/null @@ -1,89 +0,0 @@ -/*
- * Copyright 2016 Nyash (nyashh@gmail.com)
- * 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.
- * 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.Protocol;
-import org.traccar.helper.Parser;
-import org.traccar.helper.PatternBuilder;
-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 JpKorjarProtocolDecoder extends BaseProtocolDecoder {
-
- public JpKorjarProtocolDecoder(Protocol protocol) {
- super(protocol);
- }
-
- private static final Pattern PATTERN = new PatternBuilder()
- .text("KORJAR.PL,")
- .number("(d+),") // imei
- .number("(dd)(dd)(dd)") // date (yymmdd)
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .number("(d+.d+)([NS]),") // latitude
- .number("(d+.d+)([EW]),") // longitude
- .number("(d+.d+),") // speed
- .number("(d+),") // course
- .number("[FL]:(d+.d+)V,") // battery
- .number("([01]) ") // valid
- .number("(d+) ") // mcc
- .number("(d+) ") // mnc
- .number("(x+) ") // lac
- .number("(x+),") // cid
- .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;
- }
-
- Position position = new Position(getProtocolName());
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- position.setTime(parser.nextDateTime());
-
- position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
- position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
- position.setSpeed(parser.nextDouble(0));
- position.setCourse(parser.nextDouble(0));
-
- position.set(Position.KEY_BATTERY, parser.nextDouble(0));
-
- position.setValid(parser.nextInt(0) == 1);
-
- position.setNetwork(new Network(CellTower.from(
- parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0))));
-
- return position;
- }
-
-}
diff --git a/src/org/traccar/protocol/Jt600FrameDecoder.java b/src/org/traccar/protocol/Jt600FrameDecoder.java deleted file mode 100644 index b5d060ecc..000000000 --- a/src/org/traccar/protocol/Jt600FrameDecoder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.protocol; - -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 BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - char type = (char) buf.getByte(buf.readerIndex()); - - if (type == '$') { - boolean longFormat = buf.getUnsignedByte(buf.readerIndex() + 1) == 0x75; - int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10; - if (length <= buf.readableBytes()) { - return buf.readRetainedSlice(length); - } - } else if (type == '(') { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ')'); - if (endIndex != -1) { - return buf.readRetainedSlice(endIndex + 1); - } - } else { - throw new ParseException(null, 0); // unknown message - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Jt600Protocol.java b/src/org/traccar/protocol/Jt600Protocol.java deleted file mode 100644 index 97c5fa6ce..000000000 --- a/src/org/traccar/protocol/Jt600Protocol.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class Jt600Protocol extends BaseProtocol { - - public Jt600Protocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ENGINE_STOP, - Command.TYPE_SET_TIMEZONE, - Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Jt600FrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Jt600ProtocolEncoder()); - pipeline.addLast(new Jt600ProtocolDecoder(Jt600Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java deleted file mode 100644 index 1351706e2..000000000 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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.protocol; - -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.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.BitBuffer; -import org.traccar.helper.BitUtil; -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.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class Jt600ProtocolDecoder extends BaseProtocolDecoder { - - public Jt600ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static double convertCoordinate(int raw) { - int degrees = raw / 1000000; - double minutes = (raw % 1000000) / 10000.0; - return degrees + minutes / 60; - } - - 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<>(); - - buf.readByte(); // header - - boolean longFormat = buf.getUnsignedByte(buf.readerIndex()) == 0x75; - - String id = String.valueOf(Long.parseLong(ByteBufUtil.hexDump(buf.readSlice(5)))); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - int protocolVersion = 0; - if (longFormat) { - protocolVersion = buf.readUnsignedByte(); - } - - int version = BitUtil.from(buf.readUnsignedByte(), 4); - buf.readUnsignedShort(); // length - - while (buf.readableBytes() > 1) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDay(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setYear(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); - double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - - byte flags = buf.readByte(); - position.setValid((flags & 0x1) == 0x1); - if ((flags & 0x2) == 0) { - latitude = -latitude; - } - position.setLatitude(latitude); - if ((flags & 0x4) == 0) { - longitude = -longitude; - } - position.setLongitude(longitude); - - position.setSpeed(BcdUtil.readInteger(buf, 2)); - position.setCourse(buf.readUnsignedByte() * 2.0); - - if (longFormat) { - - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - buf.readUnsignedInt(); // vehicle id combined - - 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) { - position.set(Position.KEY_CHARGE, true); - } else { - position.set(Position.KEY_BATTERY_LEVEL, battery); - } - - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - position.setNetwork(new Network(cellTower)); - - if (protocolVersion == 0x17) { - buf.readUnsignedByte(); // geofence id - buf.skipBytes(3); // reserved - } - - } else if (version == 1) { - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedByte()); - - buf.readByte(); // other flags and sensors - - position.setAltitude(buf.readUnsignedShort()); - - int cid = buf.readUnsignedShort(); - int lac = buf.readUnsignedShort(); - int rssi = buf.readUnsignedByte(); - - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); - cellTower.setSignalStrength(rssi); - position.setNetwork(new Network(cellTower)); - } else { - position.set(Position.KEY_RSSI, rssi); - } - - } else if (version == 2) { - - int fuel = buf.readUnsignedByte() << 8; - - decodeStatus(position, buf); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - - fuel += buf.readUnsignedByte(); - position.set(Position.KEY_FUEL_LEVEL, fuel); - - } else if (version == 3) { - - BitBuffer bitBuffer = new BitBuffer(buf); - - position.set("fuel1", bitBuffer.readUnsigned(12)); - position.set("fuel2", bitBuffer.readUnsigned(12)); - position.set("fuel3", bitBuffer.readUnsigned(12)); - position.set(Position.KEY_ODOMETER, bitBuffer.readUnsigned(20) * 1000); - - int status = bitBuffer.readUnsigned(24); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); - position.set(Position.KEY_STATUS, status); - - } - - positions.add(position); - - } - - buf.readUnsignedByte(); // index - - return positions; - } - - private static final Pattern PATTERN_W01 = new PatternBuilder() - .text("(") - .number("(d+),") // id - .text("W01,") // type - .number("(ddd)(dd.dddd),") // longitude - .expression("([EW]),") - .number("(dd)(dd.dddd),") // latitude - .expression("([NS]),") - .expression("([AV]),") // validity - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // power - .number("(d+),") // gps signal - .number("(d+),") // gsm signal - .number("(d+),") // alert type - .any() - .compile(); - - private Position decodeW01(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_W01, 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()); - - position.setLongitude(parser.nextCoordinate()); - position.setLatitude(parser.nextCoordinate()); - position.setValid(parser.next().equals("A")); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_POWER, parser.nextDouble(0)); - position.set(Position.KEY_GPS, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set("alertType", parser.nextInt(0)); - - return position; - } - - private static final Pattern PATTERN_U01 = new PatternBuilder() - .text("(") - .number("(d+),") // id - .number("(Udd),") // type - .number("d+,").optional() // alarm - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([TF]),") // validity - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+)%,") // battery - .expression("([01]+),") // status - .number("(d+),") // cid - .number("(d+),") // lac - .number("(d+),") // gsm signal - .number("(d+),") // odometer - .number("(d+)") // serial number - .number(",(xx)").optional() // checksum - .any() - .compile(); - - private Position decodeU01(String sentence, Channel channel, SocketAddress remoteAddress) { - - Parser parser = new Parser(PATTERN_U01, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - String type = parser.next(); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("T")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - position.set(Position.KEY_STATUS, parser.nextBinInt(0)); - - CellTower cellTower = CellTower.fromCidLac(parser.nextInt(0), parser.nextInt(0)); - cellTower.setSignalStrength(parser.nextInt(0)); - position.setNetwork(new Network(cellTower)); - - position.set(Position.KEY_ODOMETER, parser.nextLong(0) * 1000); - position.set(Position.KEY_INDEX, parser.nextInt(0)); - - if (channel != null) { - if (type.equals("U01") || type.equals("U02") || type.equals("U03")) { - channel.writeAndFlush(new NetworkMessage("(S39)", remoteAddress)); - } else if (type.equals("U06")) { - channel.writeAndFlush(new NetworkMessage("(S20)", remoteAddress)); - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - char first = (char) buf.getByte(0); - - if (first == '$') { - return decodeBinary(buf, channel, remoteAddress); - } else if (first == '(') { - String sentence = buf.toString(StandardCharsets.US_ASCII); - if (sentence.contains("W01")) { - return decodeW01(sentence, channel, remoteAddress); - } else { - return decodeU01(sentence, channel, remoteAddress); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/org/traccar/protocol/Jt600ProtocolEncoder.java deleted file mode 100644 index fe5c63c32..000000000 --- a/src/org/traccar/protocol/Jt600ProtocolEncoder.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * 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 java.util.TimeZone; - -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class Jt600ProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return "(S07,0)"; - case Command.TYPE_ENGINE_RESUME: - return "(S07,1)"; - case Command.TYPE_SET_TIMEZONE: - int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; - return "(S09,1," + offset + ")"; - case Command.TYPE_REBOOT_DEVICE: - return "(S17)"; - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/KenjiProtocol.java b/src/org/traccar/protocol/KenjiProtocol.java deleted file mode 100644 index 90c0c511c..000000000 --- a/src/org/traccar/protocol/KenjiProtocol.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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; - -public class KenjiProtocol extends BaseProtocol { - - public KenjiProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new KenjiProtocolDecoder(KenjiProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/KenjiProtocolDecoder.java b/src/org/traccar/protocol/KenjiProtocolDecoder.java deleted file mode 100644 index 63812242a..000000000 --- a/src/org/traccar/protocol/KenjiProtocolDecoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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.util.regex.Pattern; - -public class KenjiProtocolDecoder extends BaseProtocolDecoder { - - public KenjiProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text(">") - .number("C(d{6}),") // device id - .number("M(x{6}),") // alarm - .number("O(x{4}),") // output - .number("I(x{4}),") // input - .number("D(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // valid - .number("([NS])(dd)(dd.d+),") // latitude - .number("([EW])(ddd)(dd.d+),") // longitude - .number("T(d+.d+),") // speed - .number("H(d+.d+),") // course - .number("Y(dd)(dd)(dd),") // date (ddmmyy) - .number("G(d+)") // satellites - .any() - .compile(); - - private String decodeAlarm(int value) { - if (BitUtil.check(value, 2)) { - return Position.ALARM_SOS; - } - if (BitUtil.check(value, 4)) { - return Position.ALARM_LOW_BATTERY; - } - if (BitUtil.check(value, 6)) { - return Position.ALARM_MOVEMENT; - } - if (BitUtil.check(value, 1) || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { - return Position.ALARM_VIBRATION; - } - - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt(0))); - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/KhdProtocol.java b/src/org/traccar/protocol/KhdProtocol.java deleted file mode 100644 index cec7158ed..000000000 --- a/src/org/traccar/protocol/KhdProtocol.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class KhdProtocol extends BaseProtocol { - - public KhdProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); - pipeline.addLast(new KhdProtocolEncoder()); - pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/KhdProtocolDecoder.java b/src/org/traccar/protocol/KhdProtocolDecoder.java deleted file mode 100644 index 0dd5b085a..000000000 --- a/src/org/traccar/protocol/KhdProtocolDecoder.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class KhdProtocolDecoder extends BaseProtocolDecoder { - - public KhdProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private String readSerialNumber(ByteBuf buf) { - int b1 = buf.readUnsignedByte(); - int b2 = buf.readUnsignedByte() - 0x80; - int b3 = buf.readUnsignedByte() - 0x80; - int b4 = buf.readUnsignedByte(); - return String.format("%02d%02d%02d%02d", b1, b2, b3, b4); - } - - public static final int MSG_LOGIN = 0xB1; - public static final int MSG_CONFIRMATION = 0x21; - public static final int MSG_ON_DEMAND = 0x81; - public static final int MSG_POSITION_UPLOAD = 0x80; - public static final int MSG_POSITION_REUPLOAD = 0x8E; - public static final int MSG_ALARM = 0x82; - public static final int MSG_ADMIN_NUMBER = 0x83; - public static final int MSG_SEND_TEXT = 0x84; - public static final int MSG_REPLY = 0x85; - public static final int MSG_SMS_ALARM_SWITCH = 0x86; - public static final int MSG_PERIPHERAL = 0xA3; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - int type = buf.readUnsignedByte(); - buf.readUnsignedShort(); // size - - if (type == MSG_LOGIN || type == MSG_ADMIN_NUMBER || type == MSG_SEND_TEXT - || type == MSG_SMS_ALARM_SWITCH || type == MSG_POSITION_REUPLOAD) { - - ByteBuf response = Unpooled.buffer(); - response.writeByte(0x29); - response.writeByte(0x29); // header - response.writeByte(MSG_CONFIRMATION); - response.writeShort(5); // size - response.writeByte(buf.getByte(buf.writerIndex() - 2)); - response.writeByte(type); - response.writeByte(buf.writerIndex() > 9 ? buf.getByte(9) : 0); // 10th byte - response.writeByte(Checksum.xor(response.nioBuffer())); - response.writeByte(0x0D); // ending - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - } - - if (type == MSG_ON_DEMAND || type == MSG_POSITION_UPLOAD || type == MSG_POSITION_REUPLOAD - || type == MSG_ALARM || type == MSG_REPLY || type == MSG_PERIPHERAL) { - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readSerialNumber(buf)); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - position.setLatitude(BcdUtil.readCoordinate(buf)); - position.setLongitude(BcdUtil.readCoordinate(buf)); - position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4))); - position.setCourse(BcdUtil.readInteger(buf, 4)); - position.setValid((buf.readUnsignedByte() & 0x80) != 0); - - if (type != MSG_ALARM) { - - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_HDOP, buf.readUnsignedByte()); - position.set(Position.KEY_VDOP, buf.readUnsignedByte()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - buf.skipBytes(5); // other location data - - if (type == MSG_PERIPHERAL) { - - buf.readUnsignedShort(); // data length - - int dataType = buf.readUnsignedByte(); - - buf.readUnsignedByte(); // content length - - switch (dataType) { - case 0x01: - position.set(Position.KEY_FUEL_LEVEL, - buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); - break; - case 0x02: - position.set(Position.PREFIX_TEMP + 1, - buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); - break; - default: - break; - } - - } - - } - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/KhdProtocolEncoder.java b/src/org/traccar/protocol/KhdProtocolEncoder.java deleted file mode 100644 index c66129283..000000000 --- a/src/org/traccar/protocol/KhdProtocolEncoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -public class KhdProtocolEncoder extends BaseProtocolEncoder { - - public static final int MSG_CUT_OIL = 0x39; - public static final int MSG_RESUME_OIL = 0x38; - - private ByteBuf encodeCommand(int command, String uniqueId) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte(0x29); - buf.writeByte(0x29); - - buf.writeByte(command); - buf.writeShort(6); // size - - 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.nioBuffer())); - buf.writeByte(0x0D); // ending - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - String uniqueId = getUniqueId(command.getDeviceId()); - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return encodeCommand(MSG_CUT_OIL, uniqueId); - case Command.TYPE_ENGINE_RESUME: - return encodeCommand(MSG_RESUME_OIL, uniqueId); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/L100FrameDecoder.java b/src/org/traccar/protocol/L100FrameDecoder.java deleted file mode 100644 index 158461895..000000000 --- a/src/org/traccar/protocol/L100FrameDecoder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - * 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; - -import java.nio.charset.StandardCharsets; - -public class L100FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - if (buf.getCharSequence(buf.readerIndex(), 4, StandardCharsets.US_ASCII).toString().equals("ATL,")) { - return decodeNew(buf); - } else { - return decodeOld(buf); - } - } - - private Object decodeOld(ByteBuf buf) { - - 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 < 0) { - index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04); - if (index < 0) { - return null; - } - } - } - - index += 2; // checksum - - 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; - } - - private Object decodeNew(ByteBuf buf) { - - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '@'); - if (index < 0) { - return null; - } - - if (buf.writerIndex() >= index + 1) { - ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex()); - buf.skipBytes(1); // delimiter - return frame; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/L100Protocol.java b/src/org/traccar/protocol/L100Protocol.java deleted file mode 100644 index 942029307..000000000 --- a/src/org/traccar/protocol/L100Protocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class L100Protocol extends BaseProtocol { - - public L100Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new L100FrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new L100ProtocolDecoder(L100Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/L100ProtocolDecoder.java b/src/org/traccar/protocol/L100ProtocolDecoder.java deleted file mode 100644 index 9868de435..000000000 --- a/src/org/traccar/protocol/L100ProtocolDecoder.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2016 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.ObdDecoder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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 L100ProtocolDecoder extends BaseProtocolDecoder { - - public L100ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("ATL") - .expression(",[^,]+,").optional() - .number("(d{15}),") // imei - .text("$GPRMC,") - .number("(dd)(dd)(dd)") // time (hhmmss.sss) - .number(".(ddd)").optional() - .expression(",([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .any() - .text("#") - .number("([01]+),") // io status - .number("(d+.?d*|N.C),") // adc - .expression("[^,]*,") // reserved - .expression("[^,]*,") // reserved - .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_LOCATION = 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(); - - private static final Pattern PATTERN_OBD_DATA = new PatternBuilder() - .expression("[LH],") // archive - .text("ATLOBD,") - .number("(d{15}),") // imei - .number("d+,") // type - .number("d+,") // index - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("[^,]+,") // obd protocol - .expression("(.+)") // data - .compile(); - - private static final Pattern PATTERN_NEW = new PatternBuilder() - .groupBegin() - .text("ATL,") - .expression("[LH],") // archive - .number("(d{15}),") // imei - .groupEnd("?") - .expression("([NPT]),") // alarm - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .number("(d+.?d*),") // speed - .expression("(?:GPS|GSM|INV),") - .number("(d+),") // battery - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(d+),") // lac - .number("(d+)") // cid - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("L") || sentence.startsWith("H")) { - if (sentence.substring(2, 8).equals("ATLOBD")) { - return decodeObdData(channel, remoteAddress, sentence); - } else { - return decodeObdLocation(channel, remoteAddress, sentence); - } - } else if (!sentence.contains("$GPRMC")) { - return decodeNew(channel, remoteAddress, sentence); - } else { - return decodeNormal(channel, remoteAddress, sentence); - } - } - - private Object decodeNormal(Channel channel, SocketAddress remoteAddress, String sentence) { - - 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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(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()); - 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))); - } - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage(String.valueOf((char) 0x01), remoteAddress)); - } - - return position; - } - - private Object decodeObdLocation(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_OBD_LOCATION, 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(), 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; - } - - private Object decodeObdData(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_OBD_DATA, 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()); - - getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - for (String entry : parser.next().split(",")) { - String[] values = entry.split(":"); - if (values.length == 2 && values[1].charAt(0) != 'X') { - position.add(ObdDecoder.decodeData( - Integer.parseInt(values[0].substring(2), 16), Integer.parseInt(values[1], 16), true)); - } - } - - return position; - } - - private Object decodeNew(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_NEW, sentence); - if (!parser.matches()) { - return null; - } - - String imei = parser.next(); - DeviceSession deviceSession; - if (imei != null) { - deviceSession = getDeviceSession(channel, remoteAddress, imei); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - switch (parser.next()) { - case "P": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "T": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - default: - break; - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - 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.nextDouble()); - - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextHexInt()))); - - return position; - } - -} diff --git a/src/org/traccar/protocol/LaipacProtocol.java b/src/org/traccar/protocol/LaipacProtocol.java deleted file mode 100644 index 923b08a16..000000000 --- a/src/org/traccar/protocol/LaipacProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class LaipacProtocol extends BaseProtocol { - - public LaipacProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new LaipacProtocolDecoder(LaipacProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/LaipacProtocolDecoder.java b/src/org/traccar/protocol/LaipacProtocolDecoder.java deleted file mode 100644 index 2f3cbb1b9..000000000 --- a/src/org/traccar/protocol/LaipacProtocolDecoder.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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 LaipacProtocolDecoder extends BaseProtocolDecoder { - - public LaipacProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$AVRMC,") - .expression("([^,]+),") // identifier - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AVRPavrp]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .number("([EW]),") - .number("(d+.d+),") // speed - .number("(d+.d+),") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("([abZXTSMHFE86430]),") // event code - .expression("([\\d.]+),") // battery voltage - .number("(d+),") // current mileage - .number("(d),") // gps status - .number("(d+),") // adc1 - .number("(d+)") // adc2 - .number(",(xxxx)") // lac - .number("(xxxx),") // cid - .number("(ddd)") // mcc - .number("(ddd)") // mnc - .optional(4) - .text("*") - .number("(xx)") // checksum - .compile(); - - private String decodeAlarm(String event) { - switch (event) { - case "Z": - return Position.ALARM_LOW_BATTERY; - case "X": - return Position.ALARM_GEOFENCE_ENTER; - case "T": - return Position.ALARM_TAMPERING; - case "H": - return Position.ALARM_POWER_OFF; - case "8": - return Position.ALARM_SHOCK; - case "7": - case "4": - return Position.ALARM_GEOFENCE_EXIT; - case "6": - return Position.ALARM_OVERSPEED; - case "3": - return Position.ALARM_SOS; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("$ECHK") && channel != null) { - channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress)); // heartbeat - return null; - } - - 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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - String status = parser.next(); - 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()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - String event = parser.next(); - position.set(Position.KEY_ALARM, decodeAlarm(event)); - position.set(Position.KEY_EVENT, event); - position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001); - position.set(Position.KEY_ODOMETER, parser.nextDouble()); - position.set(Position.KEY_GPS, parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); - - Integer lac = parser.nextHexInt(); - Integer cid = parser.nextHexInt(); - Integer mcc = parser.nextInt(); - Integer mnc = parser.nextInt(); - if (lac != null && cid != null && mcc != null && mnc != null) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid))); - } - - String checksum = parser.next(); - - if (channel != null) { - if (event.equals("3")) { - channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,d*31\r\n", remoteAddress)); - } else if (event.equals("X") || event.equals("4")) { - channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,x*2D\r\n", remoteAddress)); - } else if (event.equals("Z")) { - 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.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/M2cProtocol.java b/src/org/traccar/protocol/M2cProtocol.java deleted file mode 100644 index 9de8526c3..000000000 --- a/src/org/traccar/protocol/M2cProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class M2cProtocol extends BaseProtocol { - - public M2cProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new M2cProtocolDecoder(M2cProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/M2cProtocolDecoder.java b/src/org/traccar/protocol/M2cProtocolDecoder.java deleted file mode 100644 index 1460bb176..000000000 --- a/src/org/traccar/protocol/M2cProtocolDecoder.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class M2cProtocolDecoder extends BaseProtocolDecoder { - - public M2cProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("#M2C,") - .expression("[^,]+,") // model - .expression("[^,]+,") // firmware - .number("d+,") // protocol - .number("(d+),") // imei - .number("(d+),") // index - .expression("([LH]),") // archive - .number("d+,") // priority - .number("(d+),") // event - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(-?d+),") // altitude - .number("(d+),") // course - .number("(d+.d+),") // speed - .number("(d+),") // satellites - .number("(d+),") // odometer - .number("(d+),") // input - .number("(d+),") // output - .number("(d+),") // power - .number("(d+),") // battery - .number("(d+),") // adc 1 - .number("(d+),") // adc 2 - .number("(d+.?d*),") // temperature - .any() - .compile(); - - private Position decodePosition(Channel channel, SocketAddress remoteAddress, String line) { - - Parser parser = new Parser(PATTERN, line); - 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.set(Position.KEY_INDEX, parser.nextInt()); - - if (parser.next().equals("H")) { - position.set(Position.KEY_ARCHIVE, true); - } - - position.set(Position.KEY_EVENT, parser.nextInt()); - - position.setValid(true); - position.setTime(parser.nextDateTime()); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setAltitude(parser.nextInt()); - position.setCourse(parser.nextInt()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextLong()); - position.set(Position.KEY_INPUT, parser.nextInt()); - position.set(Position.KEY_OUTPUT, parser.nextInt()); - position.set(Position.KEY_POWER, parser.nextInt() * 0.001); - position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); - position.set(Position.PREFIX_ADC + 1, parser.nextInt()); - position.set(Position.PREFIX_ADC + 2, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble()); - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - sentence = sentence.substring(1); // remove start symbol - - List<Position> positions = new LinkedList<>(); - for (String line : sentence.split("\r\n")) { - if (!line.isEmpty()) { - Position position = decodePosition(channel, remoteAddress, line); - if (position != null) { - positions.add(position); - } - } - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/M2mProtocol.java b/src/org/traccar/protocol/M2mProtocol.java deleted file mode 100644 index dda328a59..000000000 --- a/src/org/traccar/protocol/M2mProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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.FixedLengthFrameDecoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class M2mProtocol extends BaseProtocol { - - public M2mProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new FixedLengthFrameDecoder(23)); - pipeline.addLast(new M2mProtocolDecoder(M2mProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/M2mProtocolDecoder.java b/src/org/traccar/protocol/M2mProtocolDecoder.java deleted file mode 100644 index 21e4a2fd0..000000000 --- a/src/org/traccar/protocol/M2mProtocolDecoder.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class M2mProtocolDecoder extends BaseProtocolDecoder { - - public M2mProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private boolean firstPacket = true; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - // Remove offset - for (int i = 0; i < buf.readableBytes(); i++) { - int b = buf.getByte(i); - if (b != 0x0b) { - buf.setByte(i, b - 0x20); - } - } - - if (firstPacket) { - - firstPacket = false; - - StringBuilder imei = new StringBuilder(); - for (int i = 0; i < 8; i++) { - int b = buf.readByte(); - if (i != 0) { - imei.append(b / 10); - } - imei.append(b % 10); - } - - getDeviceSession(channel, remoteAddress, imei.toString()); - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDay(buf.readUnsignedByte() & 0x3f) - .setMonth(buf.readUnsignedByte() & 0x3f) - .setYear(buf.readUnsignedByte()) - .setHour(buf.readUnsignedByte() & 0x3f) - .setMinute(buf.readUnsignedByte() & 0x7f) - .setSecond(buf.readUnsignedByte() & 0x7f); - position.setTime(dateBuilder.getDate()); - - int degrees = buf.readUnsignedByte(); - double latitude = buf.readUnsignedByte(); - latitude += buf.readUnsignedByte() / 100.0; - latitude += buf.readUnsignedByte() / 10000.0; - latitude /= 60; - latitude += degrees; - - int b = buf.readUnsignedByte(); - - degrees = (b & 0x7f) * 100 + buf.readUnsignedByte(); - double longitude = buf.readUnsignedByte(); - longitude += buf.readUnsignedByte() / 100.0; - longitude += buf.readUnsignedByte() / 10000.0; - longitude /= 60; - longitude += degrees; - - if ((b & 0x80) != 0) { - longitude = -longitude; - } - if ((b & 0x40) != 0) { - latitude = -latitude; - } - - position.setValid(true); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setSpeed(buf.readUnsignedByte()); - - int satellites = buf.readUnsignedByte(); - if (satellites == 0) { - return null; // cell information - } - position.set(Position.KEY_SATELLITES, satellites); - - // decode other data - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MaestroProtocol.java b/src/org/traccar/protocol/MaestroProtocol.java deleted file mode 100644 index 87453ce7d..000000000 --- a/src/org/traccar/protocol/MaestroProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class MaestroProtocol extends BaseProtocol { - - public MaestroProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new FixedLengthFrameDecoder(160)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MaestroProtocolDecoder(MaestroProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MaestroProtocolDecoder.java b/src/org/traccar/protocol/MaestroProtocolDecoder.java deleted file mode 100644 index 37b097414..000000000 --- a/src/org/traccar/protocol/MaestroProtocolDecoder.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 MaestroProtocolDecoder extends BaseProtocolDecoder { - - public MaestroProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("@") - .number("(d+),") // imei - .number("d+,") // index - .expression("[^,]+,") // profile - .expression("([01]),") // validity - .number("(d+.d+),") // battery - .number("(d+),") // gsm - .expression("([01]),") // starter - .expression("([01]),") // ignition - .number("(dd)/(dd)/(dd),") // date (yy/mm/dd) - .number("(dd):(dd):(dd),") // time (hh:mm:ss) - .number("(-?d+.d+),") // longitude - .number("(-?d+.d+),") // latitude - .number("(d+.?d*),") // altitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+),") // satellites - .number("(d+.?d*),") // hdop - .number("(d+.?d*)") // odometer - .number(",(d+)").optional() // adc - .any() - .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(parser.nextInt(0) == 1); - - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1609.34); - - if (parser.hasNext()) { - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/ManPowerProtocol.java b/src/org/traccar/protocol/ManPowerProtocol.java deleted file mode 100644 index 49d8b1e9f..000000000 --- a/src/org/traccar/protocol/ManPowerProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class ManPowerProtocol extends BaseProtocol { - - public ManPowerProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new ManPowerProtocolDecoder(ManPowerProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/org/traccar/protocol/ManPowerProtocolDecoder.java deleted file mode 100644 index 2c7b7eb40..000000000 --- a/src/org/traccar/protocol/ManPowerProtocolDecoder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class ManPowerProtocolDecoder extends BaseProtocolDecoder { - - public ManPowerProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("simei:") - .number("(d+),") // imei - .expression("[^,]*,[^,]*,") - .expression("([^,]*),") // status - .number("d+,d+,d+.?d*,") - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.dddd),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.dddd),") // longitude - .expression("([EW])?,") - .number("(d+.?d*),") // speed - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_STATUS, parser.next()); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/MegastekFrameDecoder.java b/src/org/traccar/protocol/MegastekFrameDecoder.java deleted file mode 100644 index 347fa24b1..000000000 --- a/src/org/traccar/protocol/MegastekFrameDecoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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; -import org.traccar.helper.BufferUtil; - -import java.nio.charset.StandardCharsets; - -public class MegastekFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - 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.readRetainedSlice(length); - } - } else { - while (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n') { - buf.skipBytes(1); - } - int delimiter = BufferUtil.indexOf("\r\n", buf); - if (delimiter == -1) { - delimiter = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '!'); - } - if (delimiter != -1) { - ByteBuf result = buf.readRetainedSlice(delimiter - buf.readerIndex()); - buf.skipBytes(1); - return result; - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MegastekProtocol.java b/src/org/traccar/protocol/MegastekProtocol.java deleted file mode 100644 index e9f5f9fde..000000000 --- a/src/org/traccar/protocol/MegastekProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class MegastekProtocol extends BaseProtocol { - - public MegastekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MegastekFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MegastekProtocolDecoder(MegastekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java deleted file mode 100644 index d81cc0eda..000000000 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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 MegastekProtocolDecoder extends BaseProtocolDecoder { - - public MegastekProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_GPRMC = new PatternBuilder() - .text("$GPRMC,") - .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),([NS]),") // latitude - .number("(d+)(dd.d+),([EW]),") // longitude - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() // checksum - .compile(); - - private static final Pattern PATTERN_SIMPLE = new PatternBuilder() - .expression("[FL],") // flag - .expression("([^,]*),") // alarm - .number("imei:(d+),") // imei - .number("(d+/?d*)?,") // satellites - .number("(d+.d+)?,") // altitude - .number("Battery=(d+)%,,?") // battery - .number("(d)?,") // charger - .number("(d+)?,") // mcc - .number("(d+)?,") // mnc - .number("(xxxx),") // lac - .number("(xxxx);") // cid - .any() // checksum - .compile(); - - private static final Pattern PATTERN_ALTERNATIVE = new PatternBuilder() - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(xxxx),") // lac - .number("(xxxx),") // cid - .number("(d+),") // gsm signal - .number("(d+),") // battery - .number("(d+),") // flags - .number("(d+),") // inputs - .number("(?:(d+),)?") // outputs - .number("(d.?d*),") // adc 1 - .groupBegin() - .number("(d.dd),") // adc 2 - .number("(d.dd),") // adc 3 - .groupEnd("?") - .expression("([^;]+);") // alarm - .any() // checksum - .compile(); - - private boolean parseLocation(String location, Position position) { - - Parser parser = new Parser(PATTERN_GPRMC, location); - if (!parser.matches()) { - return false; - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return true; - } - - private Position decodeOld(Channel channel, SocketAddress remoteAddress, String sentence) { - - // Detect type - boolean simple = sentence.charAt(3) == ',' || sentence.charAt(6) == ','; - - // Split message - String id; - String location; - String status; - if (simple) { - - int beginIndex = sentence.indexOf(',') + 1; - int endIndex = sentence.indexOf(',', beginIndex); - id = sentence.substring(beginIndex, endIndex); - - beginIndex = endIndex + 1; - endIndex = sentence.indexOf('*', beginIndex); - if (endIndex != -1) { - endIndex += 3; - } else { - endIndex = sentence.length(); - } - location = sentence.substring(beginIndex, endIndex); - - beginIndex = endIndex + 1; - if (beginIndex > sentence.length()) { - beginIndex = endIndex; - } - status = sentence.substring(beginIndex); - - } else { - - int beginIndex = 3; - int endIndex = beginIndex + 16; - id = sentence.substring(beginIndex, endIndex).trim(); - - beginIndex = endIndex + 2; - endIndex = sentence.indexOf('*', beginIndex) + 3; - location = sentence.substring(beginIndex, endIndex); - - beginIndex = endIndex + 1; - status = sentence.substring(beginIndex); - - } - - Position position = new Position(getProtocolName()); - if (!parseLocation(location, position)) { - return null; - } - - if (simple) { - - Parser parser = new Parser(PATTERN_SIMPLE, status); - if (parser.matches()) { - - position.set(Position.KEY_ALARM, decodeAlarm(parser.next())); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - String sat = parser.next(); - if (sat.contains("/")) { - position.set(Position.KEY_SATELLITES, Integer.parseInt(sat.split("/")[0])); - position.set(Position.KEY_SATELLITES_VISIBLE, Integer.parseInt(sat.split("/")[1])); - } else { - position.set(Position.KEY_SATELLITES, Integer.parseInt(sat)); - } - - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextDouble(0)); - - String charger = parser.next(); - if (charger != null) { - position.set(Position.KEY_CHARGE, Integer.parseInt(charger) == 1); - } - - if (parser.hasNext(4)) { - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - } - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - } - - } else { - - Parser parser = new Parser(PATTERN_ALTERNATIVE, status); - if (parser.matches()) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setNetwork(new Network(CellTower.from(parser.nextInt(0), parser.nextInt(0), - parser.nextHexInt(0), parser.nextHexInt(0), parser.nextInt(0)))); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextDouble()); - - position.set(Position.KEY_FLAGS, parser.next()); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.PREFIX_ADC + 3, parser.next()); - position.set(Position.KEY_ALARM, decodeAlarm(parser.next())); - - } - } - - return position; - } - - private static final Pattern PATTERN_NEW = new PatternBuilder() - .number("dddd").optional() - .text("$MGV") - .number("ddd,") - .number("(d+),") // imei - .expression("[^,]*,") // name - .expression("([RS]),") - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),([NS]),") // latitude - .number("(d+)(dd.d+),([EW]),") // longitude - .number("dd,") - .number("(dd),") // satellites - .number("dd,") - .number("(d+.d+),") // hdop - .number("(d+.d+)?,") // speed - .number("(d+.d+)?,") // course - .number("(-?d+.d+),") // altitude - .number("(d+.d+)?,") // odometer - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(xxxx)?,") // lac - .number("(x+)?,") // cid - .number("(d+)?,") // gsm - .groupBegin() - .number("([01]{4})?,") // input - .number("([01]{4})?,") // output - .number("(d+)?,") // adc1 - .number("(d+)?,") // adc2 - .number("(d+)?,") // adc3 - .or() - .number("(d+),") // input - .number("(d+),") // output - .number("(d+),") // adc1 - .number("(d+),") // adc2 - .number("(d+),") // adc3 - .groupEnd() - .groupBegin() - .number("(-?d+.?d*)") // temperature 1 - .or().text(" ") - .groupEnd("?").text(",") - .groupBegin() - .number("(-?d+.?d*)") // temperature 2 - .or().text(" ") - .groupEnd("?").text(",") - .number("(d+)?,") // rfid - .expression("[^,]*,") - .number("(d+)?,") // battery - .expression("([^,]*)") // alert - .any() - .compile(); - - private Position decodeNew(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_NEW, 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()); - - if (parser.next().equals("S")) { - position.set(Position.KEY_ARCHIVE, true); - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - } - - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - Integer lac = parser.nextHexInt(); - Integer cid = parser.nextHexInt(); - Integer rssi = parser.nextInt(); - if (lac != null && cid != null) { - CellTower tower = CellTower.from(mcc, mnc, lac, cid); - if (rssi != null) { - tower.setSignalStrength(rssi); - } - position.setNetwork(new Network(tower)); - } - - if (parser.hasNext(5)) { - position.set(Position.KEY_INPUT, parser.nextBinInt(0)); - position.set(Position.KEY_OUTPUT, parser.nextBinInt(0)); - for (int i = 1; i <= 3; i++) { - position.set(Position.PREFIX_ADC + i, parser.nextInt(0)); - } - } - - if (parser.hasNext(5)) { - position.set(Position.KEY_HEART_RATE, parser.nextInt()); - position.set(Position.KEY_STEPS, parser.nextInt()); - position.set("activityTime", parser.nextInt()); - position.set("lightSleepTime", parser.nextInt()); - position.set("deepSleepTime", parser.nextInt()); - } - - for (int i = 1; i <= 2; i++) { - String adc = parser.next(); - if (adc != null) { - position.set(Position.PREFIX_TEMP + i, Double.parseDouble(adc)); - } - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - String battery = parser.next(); - if (battery != null) { - position.set(Position.KEY_BATTERY, Integer.parseInt(battery)); - } - - position.set(Position.KEY_ALARM, decodeAlarm(parser.next())); - - return position; - } - - private String decodeAlarm(String value) { - value = value.toLowerCase(); - if (value.startsWith("geo")) { - if (value.endsWith("in")) { - return Position.ALARM_GEOFENCE_ENTER; - } else if (value.endsWith("out")) { - return Position.ALARM_GEOFENCE_EXIT; - } - } - switch (value) { - case "poweron": - return Position.ALARM_POWER_ON; - case "poweroff": - return Position.ALARM_POWER_ON; - case "sos": - case "help": - return Position.ALARM_SOS; - case "over speed": - case "overspeed": - return Position.ALARM_OVERSPEED; - case "lowspeed": - return Position.ALARM_LOW_SPEED; - case "low battery": - case "lowbattery": - return Position.ALARM_LOW_BATTERY; - case "vib": - return Position.ALARM_VIBRATION; - case "move in": - return Position.ALARM_GEOFENCE_ENTER; - case "move out": - return Position.ALARM_GEOFENCE_EXIT; - case "error": - return Position.ALARM_FAULT; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.contains("$MG")) { - return decodeNew(channel, remoteAddress, sentence); - } else { - return decodeOld(channel, remoteAddress, sentence); - } - } - -} diff --git a/src/org/traccar/protocol/MeiligaoFrameDecoder.java b/src/org/traccar/protocol/MeiligaoFrameDecoder.java deleted file mode 100644 index 52f9ae26d..000000000 --- a/src/org/traccar/protocol/MeiligaoFrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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 MeiligaoFrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_HEADER = 4; - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - // Strip not '$' (0x24) bytes from the beginning - while (buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) != 0x24) { - buf.readByte(); - } - - // Check length and return buffer - if (buf.readableBytes() >= MESSAGE_HEADER) { - int length = buf.getUnsignedShort(buf.readerIndex() + 2); - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MeiligaoProtocol.java b/src/org/traccar/protocol/MeiligaoProtocol.java deleted file mode 100644 index c307c7318..000000000 --- a/src/org/traccar/protocol/MeiligaoProtocol.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class MeiligaoProtocol extends BaseProtocol { - - public MeiligaoProtocol() { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ALARM_GEOFENCE, - Command.TYPE_SET_TIMEZONE, - Command.TYPE_REQUEST_PHOTO, - Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MeiligaoFrameDecoder()); - pipeline.addLast(new MeiligaoProtocolEncoder()); - pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MeiligaoProtocolEncoder()); - pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java deleted file mode 100644 index cbfc3660a..000000000 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ /dev/null @@ -1,499 +0,0 @@ -/* - * 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.protocol; - -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.Protocol; -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; -import org.traccar.model.Position; - -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(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .expression("[^\\|]*") - .groupBegin() - .number("|(d+.d+)?") // hdop - .number("|(-?d+.?d*)?") // altitude - .number("|(xxxx)?") // state - .groupBegin() - .number("|(xxxx),(xxxx)") // adc - .number(",(xxxx)").optional() - .number(",(xxxx)").optional() - .number(",(xxxx)").optional() - .number(",(xxxx)").optional() - .number(",(xxxx)").optional() - .number(",(xxxx)").optional() - .groupBegin() - .number("|x{16,20}") // cell - .number("|(xx)") // rssi - .number("|(x{8})") // odometer - .groupBegin() - .number("|(xx)") // satellites - .text("|") - .expression("(.*)") // driver - .groupEnd("?") - .or() - .number("|(d{1,9})") // odometer - .groupBegin() - .number("|(x{5,})") // rfid - .groupEnd("?") - .groupEnd("?") - .groupEnd("?") - .groupEnd("?") - .any() - .compile(); - - private static final Pattern PATTERN_RFID = new PatternBuilder() - .number("|(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW])") - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .number("(d+.d+),") // battery - .number("(d+),") // rpm - .number("(d+),") // speed - .number("(d+.d+),") // throttle - .number("(d+.d+),") // engine load - .number("(-?d+),") // coolant temp - .number("(d+.d+),") // instantaneous fuel - .number("(d+.d+),") // average fuel - .number("(d+.d+),") // driving range - .number("(d+.?d*),") // odometer - .number("(d+.d+),") // single fuel consumption - .number("(d+.d+),") // total fuel consumption - .number("(d+),") // error code count - .number("(d+),") // hard acceleration count - .number("(d+)") // hard brake count - .compile(); - - private static final Pattern PATTERN_OBDA = new PatternBuilder() - .number("(d+),") // total ignition - .number("(d+.d+),") // total driving time - .number("(d+.d+),") // total idling time - .number("(d+),") // average hot start time - .number("(d+),") // average speed - .number("(d+),") // history highest speed - .number("(d+),") // history highest rpm - .number("(d+),") // total hard acceleration - .number("(d+)") // total hard brake - .compile(); - - public static final int MSG_HEARTBEAT = 0x0001; - public static final int MSG_SERVER = 0x0002; - public static final int MSG_LOGIN = 0x5000; - public static final int MSG_LOGIN_RESPONSE = 0x4000; - public static final int MSG_POSITION = 0x9955; - public static final int MSG_POSITION_LOGGED = 0x9016; - public static final int MSG_ALARM = 0x9999; - public static final int MSG_RFID = 0x9966; - public static final int MSG_RETRANSMISSION = 0x6688; - - public static final int MSG_OBD_RT = 0x9901; - public static final int MSG_OBD_RTA = 0x9902; - - 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++) { - int b = buf.readUnsignedByte(); - - // First digit - int d1 = (b & 0xf0) >> 4; - if (d1 == 0xf) { - break; - } - builder.append(d1); - - // Second digit - int d2 = b & 0x0f; - if (d2 == 0xf) { - break; - } - builder.append(d2); - } - - String id = builder.toString(); - - if (id.length() == 14) { - return getDeviceSession(channel, remoteAddress, id, id + Checksum.luhn(Long.parseLong(id))); - } else { - return getDeviceSession(channel, remoteAddress, id); - } - } - - private static void sendResponse( - Channel channel, SocketAddress remoteAddress, ByteBuf id, int type, ByteBuf msg) { - - if (channel != null) { - ByteBuf buf = Unpooled.buffer( - 2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2); - - buf.writeByte('@'); - buf.writeByte('@'); - buf.writeShort(buf.capacity()); - buf.writeBytes(id); - buf.writeShort(type); - buf.writeBytes(msg); - msg.release(); - buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.nioBuffer())); - buf.writeByte('\r'); - buf.writeByte('\n'); - - channel.writeAndFlush(new NetworkMessage(buf, remoteAddress)); - } - } - - private String decodeAlarm(short value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x12: - return Position.ALARM_MOVEMENT; - case 0x13: - return Position.ALARM_GEOFENCE_ENTER; - case 0x14: - return Position.ALARM_ACCIDENT; - case 0x50: - return Position.ALARM_POWER_OFF; - case 0x53: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x72: - return Position.ALARM_BRAKING; - case 0x73: - return Position.ALARM_ACCELERATION; - default: - return null; - } - } - - private Position decodeRegular(Position position, String sentence) { - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - if (parser.hasNext()) { - position.setSpeed(parser.nextDouble(0)); - } - - if (parser.hasNext()) { - position.setCourse(parser.nextDouble(0)); - } - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - - if (parser.hasNext()) { - position.setAltitude(parser.nextDouble(0)); - } - - 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()); - } - - position.set(Position.KEY_RSSI, parser.nextHexInt()); - position.set(Position.KEY_ODOMETER, parser.nextHexLong()); - position.set(Position.KEY_SATELLITES, parser.nextHexInt()); - position.set("driverLicense", parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextLong()); - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - return position; - } - - private Position decodeRfid(Position position, String sentence) { - Parser parser = new Parser(PATTERN_RFID, sentence); - if (!parser.matches()) { - return null; - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - return position; - } - - private Position decodeObd(Position position, String sentence) { - Parser parser = new Parser(PATTERN_OBD, sentence); - if (!parser.matches()) { - return null; - } - - getLastLocation(position, null); - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_OBD_SPEED, parser.nextInt()); - position.set(Position.KEY_THROTTLE, parser.nextDouble()); - position.set(Position.KEY_ENGINE_LOAD, parser.nextDouble()); - position.set(Position.KEY_COOLANT_TEMP, parser.nextInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble()); - position.set("averageFuelConsumption", parser.nextDouble()); - position.set("drivingRange", parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextDouble()); - position.set("singleFuelConsumption", 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()); - - return position; - } - - private Position decodeObdA(Position position, String sentence) { - Parser parser = new Parser(PATTERN_OBDA, sentence); - if (!parser.matches()) { - return null; - } - - getLastLocation(position, null); - - position.set("totalIgnitionNo", parser.nextInt(0)); - position.set("totalDrivingTime", parser.nextDouble(0)); - position.set("totalIdlingTime", parser.nextDouble(0)); - position.set("averageHotStartTime", parser.nextInt(0)); - position.set("averageSpeed", parser.nextInt(0)); - position.set("historyHighestSpeed", parser.nextInt(0)); - position.set("historyHighestRpm", parser.nextInt(0)); - position.set("totalHarshAccerleration", parser.nextInt(0)); - position.set("totalHarshBrake", parser.nextInt(0)); - - return position; - } - - private List<Position> decodeRetransmission(ByteBuf buf, DeviceSession deviceSession) { - List<Position> positions = new LinkedList<>(); - - int count = buf.readUnsignedByte(); - for (int i = 0; i < count; i++) { - - buf.readUnsignedByte(); // alarm - - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\\'); - if (endIndex < 0) { - endIndex = buf.writerIndex() - 4; - } - - String sentence = buf.readSlice(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position = decodeRegular(position, sentence); - - if (position != null) { - positions.add(position); - } - - if (buf.readableBytes() > 4) { - buf.readUnsignedByte(); // delimiter - } - - } - - return positions; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - buf.skipBytes(2); // header - buf.readShort(); // length - ByteBuf id = buf.readSlice(7); - int command = buf.readUnsignedShort(); - - 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); - if (deviceSession == null) { - return null; - } - - 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); - - } else { - - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - - if (command == MSG_ALARM) { - short alarmCode = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, decodeAlarm(alarmCode)); - if (alarmCode >= 0x02 && alarmCode <= 0x05) { - position.set(Position.PREFIX_IN + alarmCode, 1); - } else if (alarmCode >= 0x32 && alarmCode <= 0x35) { - position.set(Position.PREFIX_IN + (alarmCode - 0x30), 0); - } - } else if (command == MSG_POSITION_LOGGED) { - buf.skipBytes(6); - } else if (command == MSG_RFID) { - for (int i = 0; i < 15; i++) { - long rfid = buf.readUnsignedInt(); - if (rfid != 0) { - String card = String.format("%010d", rfid); - position.set("card" + (i + 1), card); - 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); - - 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; - } - - } - } - -} diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java deleted file mode 100644 index 57cbbe0fc..000000000 --- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; -import java.util.TimeZone; - -public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(long deviceId, int type, ByteBuf content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte('@'); - buf.writeByte('@'); - - buf.writeShort(2 + 2 + 7 + 2 + content.readableBytes() + 2 + 2); // message length - - buf.writeBytes(DataConverter.parseHex((getUniqueId(deviceId) + "FFFFFFFFFFFFFF").substring(0, 14))); - - buf.writeShort(type); - - buf.writeBytes(content); - - buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.nioBuffer())); - - buf.writeByte('\r'); - buf.writeByte('\n'); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - ByteBuf content = Unpooled.buffer(); - - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - 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(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); - case Command.TYPE_ENGINE_STOP: - content.writeByte(0x01); - return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL, content); - case Command.TYPE_ENGINE_RESUME: - content.writeByte(0x00); - 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(), 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(), 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(), MeiligaoProtocolDecoder.MSG_REBOOT_GPS, content); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/MeitrackFrameDecoder.java b/src/org/traccar/protocol/MeitrackFrameDecoder.java deleted file mode 100644 index d122bca0c..000000000 --- a/src/org/traccar/protocol/MeitrackFrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -import java.nio.charset.StandardCharsets; - -public class MeitrackFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - if (index != -1) { - 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.readRetainedSlice(length); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java deleted file mode 100644 index c887cd3a0..000000000 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class MeitrackProtocol extends BaseProtocol { - - public MeitrackProtocol() { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM, - Command.TYPE_REQUEST_PHOTO, - Command.TYPE_SEND_SMS); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MeitrackFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new MeitrackProtocolEncoder()); - pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new MeitrackProtocolEncoder()); - pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java deleted file mode 100644 index 55260ef0c..000000000 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * 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.protocol; - -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.Protocol; -import org.traccar.helper.Checksum; -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.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class MeitrackProtocolDecoder extends BaseProtocolDecoder { - - private ByteBuf photo; - - public MeitrackProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$$").expression(".") // flag - .number("d+,") // length - .number("(d+),") // imei - .number("xxx,") // command - .number("d+,").optional() - .number("(d+),") // event - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("([AV]),") // validity - .number("(d+),") // satellites - .number("(d+),") // rssi - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+.?d*),") // hdop - .number("(-?d+),") // altitude - .number("(d+),") // odometer - .number("(d+),") // runtime - .number("(d+)|") // mcc - .number("(d+)|") // mnc - .number("(x+)|") // lac - .number("(x+),") // cid - .number("(x+),") // state - .number("(x+)?|") // adc1 - .number("(x+)?|") // adc2 - .number("(x+)?|") // adc3 - .number("(x+)|") // battery - .number("(x+)?,") // power - .groupBegin() - .expression("([^,]+)?,").optional() // event specific - .expression("[^,]*,") // reserved - .number("(d+)?,") // protocol - .number("(x{4})?") // fuel - .groupBegin() - .number(",(x{6}(?:|x{6})*)?") // temperature - .groupBegin() - .number(",(d+)") // data count - .expression(",([^*]*)") // data - .groupEnd("?") - .groupEnd("?") - .or() - .any() - .groupEnd() - .text("*") - .number("xx") - .text("\r\n").optional() - .compile(); - - private String decodeAlarm(int event) { - switch (event) { - case 1: - return Position.ALARM_SOS; - case 17: - return Position.ALARM_LOW_BATTERY; - case 18: - return Position.ALARM_LOW_POWER; - case 19: - return Position.ALARM_OVERSPEED; - case 20: - return Position.ALARM_GEOFENCE_ENTER; - case 21: - return Position.ALARM_GEOFENCE_EXIT; - case 22: - return Position.ALARM_POWER_RESTORED; - case 23: - return Position.ALARM_POWER_CUT; - case 36: - return Position.ALARM_TOW; - case 44: - return Position.ALARM_JAMMING; - case 78: - return Position.ALARM_ACCIDENT; - case 90: - case 91: - return Position.ALARM_CORNERING; - case 129: - return Position.ALARM_BRAKING; - case 130: - return Position.ALARM_ACCELERATION; - case 135: - return Position.ALARM_FATIGUE_DRIVING; - default: - return null; - } - } - - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII)); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - int event = parser.nextInt(0); - position.set(Position.KEY_EVENT, event); - position.set(Position.KEY_ALARM, decodeAlarm(event)); - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - int rssi = parser.nextInt(0); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set("runtime", parser.next()); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0), rssi))); - - position.set(Position.KEY_STATUS, parser.next()); - - for (int i = 1; i <= 3; i++) { - if (parser.hasNext()) { - position.set(Position.PREFIX_ADC + i, parser.nextHexInt(0)); - } - } - - String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); - if (deviceModel == null) { - deviceModel = ""; - } - switch (deviceModel.toUpperCase()) { - case "MVT340": - case "MVT380": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.0 * 2.0 / 1024.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0); - break; - case "MT90": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); - break; - case "T1": - case "T3": - case "MVT100": - case "MVT600": - case "MVT800": - case "TC68": - case "TC68S": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0); - break; - case "T311": - case "T322X": - case "T333": - case "T355": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) / 100.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); - break; - default: - position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); - break; - } - - String eventData = parser.next(); - if (eventData != null && !eventData.isEmpty()) { - switch (event) { - case 37: - position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData); - break; - default: - position.set("eventData", eventData); - break; - } - } - - int protocol = parser.nextInt(0); - - if (parser.hasNext()) { - String fuel = parser.next(); - position.set(Position.KEY_FUEL_LEVEL, - Integer.parseInt(fuel.substring(0, 2), 16) + Integer.parseInt(fuel.substring(2), 16) * 0.01); - } - - if (parser.hasNext()) { - for (String temp : parser.next().split("\\|")) { - int index = Integer.parseInt(temp.substring(0, 2), 16); - if (protocol >= 3) { - double value = (short) Integer.parseInt(temp.substring(2), 16); - position.set(Position.PREFIX_TEMP + index, value * 0.01); - } else { - double value = Byte.parseByte(temp.substring(2, 4), 16); - value += (value < 0 ? -0.01 : 0.01) * Integer.parseInt(temp.substring(4), 16); - position.set(Position.PREFIX_TEMP + index, value); - } - } - } - - if (parser.hasNext(2)) { - parser.nextInt(); // count - decodeDataFields(position, parser.next().split(",")); - } - - return position; - } - - private void decodeDataFields(Position position, String[] values) { - - if (values.length > 1 && !values[1].isEmpty()) { - position.set("tempData", values[1]); - } - - if (values.length > 5 && !values[5].isEmpty()) { - String[] data = values[5].split("\\|"); - boolean started = data[0].charAt(1) == '0'; - position.set("taximeterOn", started); - position.set("taximeterStart", data[1]); - if (data.length > 2) { - position.set("taximeterEnd", data[2]); - position.set("taximeterDistance", Integer.parseInt(data[3])); - position.set("taximeterFare", Integer.parseInt(data[4])); - position.set("taximeterTrip", data[5]); - position.set("taximeterWait", data[6]); - } - } - - } - - private List<Position> decodeBinaryC(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - List<Position> positions = new LinkedList<>(); - - String flag = buf.toString(2, 1, StandardCharsets.US_ASCII); - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - - String imei = buf.toString(index + 1, 15, StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - buf.skipBytes(index + 1 + 15 + 1 + 3 + 1 + 2 + 2 + 4); - - while (buf.readableBytes() >= 0x34) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - position.setLatitude(buf.readIntLE() * 0.000001); - position.setLongitude(buf.readIntLE() * 0.000001); - - 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.readUnsignedShortLE())); - position.setCourse(buf.readUnsignedShortLE()); - - position.set(Position.KEY_HDOP, buf.readUnsignedShortLE() * 0.1); - - position.setAltitude(buf.readUnsignedShortLE()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - position.set("runtime", buf.readUnsignedIntLE()); - - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), - buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), - rssi))); - - position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); - - 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.readUnsignedIntLE(); // geo-fence - - positions.add(position); - } - - if (channel != null) { - StringBuilder command = new StringBuilder("@@"); - command.append(flag).append(27 + positions.size() / 10).append(","); - command.append(imei).append(",CCC,").append(positions.size()).append("*"); - int checksum = 0; - for (int i = 0; i < command.length(); i += 1) { - checksum += command.charAt(i); - } - command.append(String.format("%02x", checksum & 0xff).toUpperCase()); - command.append("\r\n"); - channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data - } - - return positions; - } - - 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.readSlice(15).toString(StandardCharsets.US_ASCII); - buf.skipBytes(1 + 3 + 1); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - 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.readUnsignedShortLE(); // length - buf.readUnsignedShortLE(); // index - - int paramCount = buf.readUnsignedByte(); - for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); - switch (id) { - case 0x01: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - break; - case 0x05: - position.setValid(buf.readUnsignedByte() > 0); - break; - case 0x06: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x07: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - default: - buf.readUnsignedByte(); - break; - } - } - - paramCount = buf.readUnsignedByte(); - for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); - switch (id) { - case 0x08: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); - break; - case 0x09: - position.setCourse(buf.readUnsignedShortLE()); - break; - case 0x0B: - position.setAltitude(buf.readShortLE()); - break; - case 0x19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); - break; - case 0x1A: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); - break; - default: - buf.readUnsignedShortLE(); - break; - } - } - - paramCount = buf.readUnsignedByte(); - for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); - switch (id) { - case 0x02: - position.setLatitude(buf.readIntLE() * 0.000001); - break; - case 0x03: - position.setLongitude(buf.readIntLE() * 0.000001); - break; - case 0x04: - position.setTime(new Date((946684800 + buf.readUnsignedIntLE()) * 1000)); // 2000-01-01 - break; - case 0x0D: - position.set("runtime", buf.readUnsignedIntLE()); - break; - default: - buf.readUnsignedIntLE(); - break; - } - } - - paramCount = buf.readUnsignedByte(); - for (int j = 0; j < paramCount; j++) { - buf.readUnsignedByte(); // id - buf.skipBytes(buf.readUnsignedByte()); // value - } - - positions.add(position); - } - - return positions; - } - - 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.writeAndFlush(new NetworkMessage(response, socketAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - String imei = buf.toString(index + 1, 15, StandardCharsets.US_ASCII); - index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ','); - String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII); - - switch (type) { - case "D00": - if (photo == null) { - photo = Unpooled.buffer(); - } - - index = index + 1 + type.length() + 1; - int endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); - String file = buf.toString(index, endIndex - index, StandardCharsets.US_ASCII); - index = endIndex + 1; - endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); - int total = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII)); - index = endIndex + 1; - endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); - int current = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII)); - - buf.readerIndex(endIndex + 1); - photo.writeBytes(buf.readSlice(buf.readableBytes() - 1 - 2 - 2)); - - if (current == total - 1) { - Position position = new Position(getProtocolName()); - position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); - - 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, remoteAddress, imei, file, current + 1); - } - return null; - } - case "D03": - photo = Unpooled.buffer(); - requestPhotoPacket(channel, remoteAddress, imei, "camera_picture.jpg", 0); - return null; - case "CCC": - return decodeBinaryC(channel, remoteAddress, buf); - case "CCE": - return decodeBinaryE(channel, remoteAddress, buf); - default: - return decodeRegular(channel, remoteAddress, buf); - } - } - -} diff --git a/src/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/org/traccar/protocol/MeitrackProtocolEncoder.java deleted file mode 100644 index abb6ec9d4..000000000 --- a/src/org/traccar/protocol/MeitrackProtocolEncoder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - * 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.Context; -import org.traccar.StringProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -import java.util.Map; - -public class MeitrackProtocolEncoder extends StringProtocolEncoder { - - private Object formatCommand(Command command, char dataId, String content) { - String uniqueId = getUniqueId(command.getDeviceId()); - int length = 1 + uniqueId.length() + 1 + content.length() + 5; - String result = String.format("@@%c%02d,%s,%s*", dataId, length, uniqueId, content); - result += Checksum.sum(result) + "\r\n"; - return result; - } - - @Override - protected Object encodeCommand(Command command) { - - Map<String, Object> attributes = command.getAttributes(); - - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "meitrack.alternative", false, true); - - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, 'Q', "A10"); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, 'M', "C01,0,12222"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, 'M', "C01,0,02222"); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, 'M', alternative ? "B21,1" : "C01,0,22122"); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, 'M', alternative ? "B21,0" : "C01,0,22022"); - case Command.TYPE_REQUEST_PHOTO: - int index = command.getInteger(Command.KEY_INDEX); - return formatCommand(command, 'D', "D03," + (index > 0 ? index : 1) + ",camera_picture.jpg"); - case Command.TYPE_SEND_SMS: - return formatCommand(command, 'f', "C02,0," - + attributes.get(Command.KEY_PHONE) + "," + attributes.get(Command.KEY_MESSAGE)); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/MilesmateProtocol.java b/src/org/traccar/protocol/MilesmateProtocol.java deleted file mode 100644 index 822711603..000000000 --- a/src/org/traccar/protocol/MilesmateProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class MilesmateProtocol extends BaseProtocol { - - public MilesmateProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MilesmateProtocolDecoder(MilesmateProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MilesmateProtocolDecoder.java b/src/org/traccar/protocol/MilesmateProtocolDecoder.java deleted file mode 100644 index 901ceb8f7..000000000 --- a/src/org/traccar/protocol/MilesmateProtocolDecoder.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.DateBuilder; -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 MilesmateProtocolDecoder extends BaseProtocolDecoder { - - public MilesmateProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("ApiString={") - .number("A:(d+),") // imei - .number("B:(d+.d+),") // battery - .number("C:(d+.d+),") // adc - .number("D:(dd)(dd)(dd),") // time (hhmmss) - .number("E:(dd)(dd.d+)([NS]),") // latitude - .number("F:(ddd)(dd.d+)([EW]),") // longitude - .number("G:(d+.d+),") // speed - .number("H:(dd)(dd)(dd),") // date (ddmmyy) - .expression("I:[GL],") // location source - .number("J:(d{8}),") // flags - .number("K:(d{7})") // flags - .expression("([AV]),") // validity - .number("L:d{4},") // pin - .number("M:(d+.d+)") // course - .text("}") - .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; - } - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("+##Received OK\n", remoteAddress)); - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - String flags = parser.next(); - position.set(Position.KEY_IGNITION, flags.charAt(0) == '1'); - position.set(Position.KEY_ALARM, flags.charAt(1) == '1' ? Position.ALARM_SOS : null); - position.set(Position.KEY_CHARGE, flags.charAt(5) == '1'); - position.set(Position.KEY_ALARM, flags.charAt(7) == '1' ? Position.ALARM_OVERSPEED : null); - - flags = parser.next(); - position.set(Position.KEY_BLOCKED, flags.charAt(0) == '1'); - position.set(Position.KEY_ALARM, flags.charAt(1) == '1' ? Position.ALARM_TOW : null); - - position.setValid(parser.next().equals("A")); - - position.setCourse(parser.nextDouble()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/MiniFinderProtocol.java b/src/org/traccar/protocol/MiniFinderProtocol.java deleted file mode 100644 index d4a154053..000000000 --- a/src/org/traccar/protocol/MiniFinderProtocol.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class MiniFinderProtocol extends BaseProtocol { - - public MiniFinderProtocol() { - setSupportedDataCommands( - Command.TYPE_SET_TIMEZONE, - Command.TYPE_VOICE_MONITORING, - Command.TYPE_ALARM_SPEED, - Command.TYPE_ALARM_GEOFENCE, - Command.TYPE_ALARM_VIBRATION, - Command.TYPE_SET_AGPS, - Command.TYPE_ALARM_FALL, - Command.TYPE_MODE_POWER_SAVING, - Command.TYPE_MODE_DEEP_SLEEP, - Command.TYPE_SOS_NUMBER, - Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MiniFinderProtocolEncoder()); - pipeline.addLast(new MiniFinderProtocolDecoder(MiniFinderProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java deleted file mode 100644 index 2b7a960c4..000000000 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.regex.Pattern; - -public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { - - public MiniFinderProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_FIX = new PatternBuilder() - .number("(d+)/(d+)/(d+),") // date (dd/mm/yy) - .number("(d+):(d+):(d+),") // time (hh:mm:ss) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .compile(); - - private static final Pattern PATTERN_STATE = new PatternBuilder() - .number("(d+.?d*),") // speed (km/h) - .number("(d+.?d*),") // course - .number("(x+),") // flags - .number("(-?d+.d+),") // altitude (meters) - .number("(d+),") // battery (percentage) - .compile(); - - private static final Pattern PATTERN_A = new PatternBuilder() - .text("!A,") - .expression(PATTERN_FIX.pattern()) - .any() // unknown 3 fields - .compile(); - - private static final Pattern PATTERN_C = new PatternBuilder() - .text("!C,") - .expression(PATTERN_FIX.pattern()) - .expression(PATTERN_STATE.pattern()) - .any() // unknown 3 fields - .compile(); - - private static final Pattern PATTERN_BD = new PatternBuilder() - .expression("![BD],") // B - buffered, D - live - .expression(PATTERN_FIX.pattern()) - .expression(PATTERN_STATE.pattern()) - .number("(d+),") // satellites in use - .number("(d+),") // satellites in view - .number("(d+.?d*)") // hdop - .compile(); - - private void decodeFix(Position position, Parser parser) { - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - } - - private void decodeFlags(Position position, int flags) { - - position.setValid(BitUtil.to(flags, 2) > 0); - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_APPROXIMATE, true); - } - - if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_ALARM, Position.ALARM_FAULT); - } - if (BitUtil.check(flags, 6)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - if (BitUtil.check(flags, 7)) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - if (BitUtil.check(flags, 8)) { - position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); - } - if (BitUtil.check(flags, 9) || BitUtil.check(flags, 10) || BitUtil.check(flags, 11)) { - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - } - if (BitUtil.check(flags, 12)) { - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - } - if (BitUtil.check(flags, 15) || BitUtil.check(flags, 14)) { - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - } - - position.set(Position.KEY_RSSI, BitUtil.between(flags, 16, 21)); - position.set(Position.KEY_CHARGE, BitUtil.check(flags, 22)); - } - - private void decodeState(Position position, Parser parser) { - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - - position.setCourse(parser.nextDouble(0)); - if (position.getCourse() > 360) { - position.setCourse(0); - } - - decodeFlags(position, parser.nextHexInt(0)); - - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("!1,")) { - int index = sentence.indexOf(',', 3); - if (index < 0) { - index = sentence.length(); - } - getDeviceSession(channel, remoteAddress, sentence.substring(3, index)); - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null || !sentence.matches("![3A-D],.*")) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - String type = sentence.substring(1, 2); - position.set(Position.KEY_TYPE, type); - - if (type.equals("3")) { - - getLastLocation(position, null); - - position.set(Position.KEY_RESULT, sentence.substring(3)); - - return position; - - } else if (type.equals("B") || type.equals("D")) { - - Parser parser = new Parser(PATTERN_BD, sentence); - if (!parser.matches()) { - return null; - } - - decodeFix(position, parser); - decodeState(position, parser); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt(0)); - position.set(Position.KEY_HDOP, parser.nextDouble(0)); - - return position; - - } else if (type.equals("C")) { - - Parser parser = new Parser(PATTERN_C, sentence); - if (!parser.matches()) { - return null; - } - - decodeFix(position, parser); - decodeState(position, parser); - - return position; - - } else if (type.equals("A")) { - - Parser parser = new Parser(PATTERN_A, sentence); - if (!parser.matches()) { - return null; - } - - decodeFix(position, parser); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java deleted file mode 100644 index 7a3d5b226..000000000 --- a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 java.util.TimeZone; - -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { - - @Override - public String formatValue(String key, Object value) { - switch (key) { - case Command.KEY_ENABLE: - return (Boolean) value ? "1" : "0"; - case Command.KEY_TIMEZONE: - return String.format("%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); - case Command.KEY_INDEX: - switch (((Number) value).intValue()) { - case 0: - return "A"; - case 1: - return "B"; - case 2: - return "C"; - default: - return null; - } - default: - return null; - } - } - - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, "123456"); - - switch (command.getType()) { - case Command.TYPE_SET_TIMEZONE: - return formatCommand(command, "{%s}L{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_TIMEZONE); - case Command.TYPE_VOICE_MONITORING: - return formatCommand(command, "{%s}P{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_ALARM_SPEED: - return formatCommand(command, "{%s}J1{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_ALARM_GEOFENCE: - return formatCommand(command, "{%s}R1{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_RADIUS); - case Command.TYPE_ALARM_VIBRATION: - return formatCommand(command, "{%s}W1,{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_SET_AGPS: - return formatCommand(command, "{%s}AGPS{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_ALARM_FALL: - return formatCommand(command, "{%s}F{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_MODE_POWER_SAVING: - return formatCommand(command, "{%s}SP{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_MODE_DEEP_SLEEP: - return formatCommand(command, "{%s}DS{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_SOS_NUMBER: - return formatCommand(command, "{%s}{%s}1,{%s}", this, - Command.KEY_DEVICE_PASSWORD, Command.KEY_INDEX, Command.KEY_PHONE); - case Command.TYPE_SET_INDICATOR: - return formatCommand(command, "{%s}LED{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Mta6Protocol.java b/src/org/traccar/protocol/Mta6Protocol.java deleted file mode 100644 index 632a7df80..000000000 --- a/src/org/traccar/protocol/Mta6Protocol.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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.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; - -public class Mta6Protocol extends BaseProtocol { - - public Mta6Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); - pipeline.addLast(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 deleted file mode 100644 index 88419b871..000000000 --- a/src/org/traccar/protocol/Mta6ProtocolDecoder.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * 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. - * 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 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.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; - -public class Mta6ProtocolDecoder extends BaseProtocolDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(Mta6ProtocolDecoder.class); - - private final boolean simple; - - public Mta6ProtocolDecoder(Protocol protocol, boolean simple) { - super(protocol); - this.simple = simple; - } - - private void sendContinue(Channel channel) { - FullHttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - - private void sendResponse(Channel channel, short packetId, short packetCount) { - ByteBuf begin = Unpooled.copiedBuffer("#ACK#", StandardCharsets.US_ASCII); - ByteBuf end = Unpooled.buffer(3); - end.writeByte(packetId); - end.writeByte(packetCount); - end.writeByte(0); - - 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(ByteBuf buf) { - switch (buf.getUnsignedByte(buf.readerIndex()) >> 6) { - case 0: - previousFloat = buf.readInt() << 2; - break; - case 1: - previousFloat = (previousFloat & 0xffffff00) + ((buf.readUnsignedByte() & 0x3f) << 2); - break; - case 2: - previousFloat = (previousFloat & 0xffff0000) + ((buf.readUnsignedShort() & 0x3fff) << 2); - break; - case 3: - previousFloat = (previousFloat & 0xff000000) + ((buf.readUnsignedMedium() & 0x3fffff) << 2); - break; - default: - LOGGER.warn("MTA6 float decoding error", new IllegalArgumentException()); - break; - } - return Float.intBitsToFloat(previousFloat); - } - - } - - private static class TimeReader extends FloatReader { - - private long weekNumber; - - public Date readTime(ByteBuf buf) { - long weekTime = (long) (readFloat(buf) * 1000); - if (weekNumber == 0) { - weekNumber = buf.readUnsignedShort(); - } - - DateBuilder dateBuilder = new DateBuilder().setDate(1980, 1, 6); - dateBuilder.addMillis(weekNumber * 7 * 24 * 60 * 60 * 1000 + weekTime); - - return dateBuilder.getDate(); - } - - } - - private List<Position> parseFormatA(DeviceSession deviceSession, ByteBuf buf) { - List<Position> positions = new LinkedList<>(); - - FloatReader latitudeReader = new FloatReader(); - FloatReader longitudeReader = new FloatReader(); - TimeReader timeReader = new TimeReader(); - - try { - while (buf.isReadable()) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - short flags = buf.readUnsignedByte(); - - short event = buf.readUnsignedByte(); - if (BitUtil.check(event, 7)) { - if (BitUtil.check(event, 6)) { - buf.skipBytes(8); - } else { - while (BitUtil.check(event, 7)) { - event = buf.readUnsignedByte(); - } - } - } - - position.setLatitude(latitudeReader.readFloat(buf) / Math.PI * 180); - position.setLongitude(longitudeReader.readFloat(buf) / Math.PI * 180); - position.setTime(timeReader.readTime(buf)); - - if (BitUtil.check(flags, 0)) { - buf.readUnsignedByte(); // status - } - - if (BitUtil.check(flags, 1)) { - position.setAltitude(buf.readUnsignedShort()); - } - - if (BitUtil.check(flags, 2)) { - position.setSpeed(buf.readUnsignedShort() & 0x03ff); - position.setCourse(buf.readUnsignedByte()); - } - - if (BitUtil.check(flags, 3)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000); - } - - if (BitUtil.check(flags, 4)) { - position.set(Position.KEY_FUEL_CONSUMPTION + "Accumulator1", buf.readUnsignedInt()); - position.set(Position.KEY_FUEL_CONSUMPTION + "Accumulator2", buf.readUnsignedInt()); - position.set("hours1", buf.readUnsignedShort()); - position.set("hours2", buf.readUnsignedShort()); - } - - if (BitUtil.check(flags, 5)) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() & 0x03ff); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort() & 0x03ff); - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort() & 0x03ff); - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShort() & 0x03ff); - } - - if (BitUtil.check(flags, 6)) { - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - buf.getUnsignedByte(buf.readerIndex()); // control (>> 4) - position.set(Position.KEY_INPUT, buf.readUnsignedShort() & 0x0fff); - buf.readUnsignedShort(); // old sensor state (& 0x0fff) - } - - if (BitUtil.check(flags, 7)) { - position.set(Position.KEY_BATTERY, buf.getUnsignedByte(buf.readerIndex()) >> 2); - position.set(Position.KEY_POWER, buf.readUnsignedShort() & 0x03ff); - position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - - position.set(Position.KEY_RSSI, (buf.getUnsignedByte(buf.readerIndex()) >> 4) & 0x07); - - int satellites = buf.readUnsignedByte() & 0x0f; - position.setValid(satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - } - positions.add(position); - } - } catch (IndexOutOfBoundsException error) { - LOGGER.warn("MTA6 parsing error", error); - } - - return positions; - } - - private Position parseFormatA1(DeviceSession deviceSession, ByteBuf buf) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - short flags = buf.readUnsignedByte(); - - // Skip events - short event = buf.readUnsignedByte(); - if (BitUtil.check(event, 7)) { - if (BitUtil.check(event, 6)) { - buf.skipBytes(8); - } else { - while (BitUtil.check(event, 7)) { - event = buf.readUnsignedByte(); - } - } - } - - position.setLatitude(new FloatReader().readFloat(buf) / Math.PI * 180); - position.setLongitude(new FloatReader().readFloat(buf) / Math.PI * 180); - position.setTime(new TimeReader().readTime(buf)); - - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - - if (BitUtil.check(flags, 0)) { - position.setAltitude(buf.readUnsignedShort()); - position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readByte()); - position.set(Position.KEY_ODOMETER, new FloatReader().readFloat(buf)); - } - - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_FUEL_CONSUMPTION, new FloatReader().readFloat(buf)); - position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(new FloatReader().readFloat(buf))); - position.set("tank", buf.readUnsignedByte() * 0.4); - } - - if (BitUtil.check(flags, 2)) { - position.set("engine", buf.readUnsignedShort() * 0.125); - position.set("pedals", buf.readUnsignedByte()); - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte() - 40); - position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShort()); - } - - if (BitUtil.check(flags, 3)) { - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShort()); - } - - if (BitUtil.check(flags, 4)) { - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - buf.getUnsignedByte(buf.readerIndex()); // control (>> 4) - position.set(Position.KEY_INPUT, buf.readUnsignedShort() & 0x0fff); - buf.readUnsignedShort(); // old sensor state (& 0x0fff) - } - - if (BitUtil.check(flags, 5)) { - position.set(Position.KEY_BATTERY, buf.getUnsignedByte(buf.readerIndex()) >> 2); - position.set(Position.KEY_POWER, buf.readUnsignedShort() & 0x03ff); - position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - - position.set(Position.KEY_RSSI, buf.getUnsignedByte(buf.readerIndex()) >> 5); - - int satellites = buf.readUnsignedByte() & 0x1f; - position.setValid(satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - } - - // other data - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - ByteBuf buf = request.content(); - - buf.skipBytes("id=".length()); - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '&'); - String uniqueId = buf.toString(buf.readerIndex(), index - buf.readerIndex(), StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); - if (deviceSession == null) { - return null; - } - buf.skipBytes(uniqueId.length()); - buf.skipBytes("&bin=".length()); - - short packetId = buf.readUnsignedByte(); - short offset = buf.readUnsignedByte(); // dataOffset - short packetCount = buf.readUnsignedByte(); - buf.readUnsignedByte(); // reserved - buf.readUnsignedByte(); // timezone - buf.skipBytes(offset - 5); - - if (channel != null) { - sendContinue(channel); - sendResponse(channel, packetId, packetCount); - } - - if (packetId == 0x31 || packetId == 0x32 || packetId == 0x36) { - if (simple) { - return parseFormatA1(deviceSession, buf); - } else { - return parseFormatA(deviceSession, buf); - } - } // else if (0x34 0x38 0x4F 0x59) - - return null; - } - -} diff --git a/src/org/traccar/protocol/MtxProtocol.java b/src/org/traccar/protocol/MtxProtocol.java deleted file mode 100644 index 44372ce83..000000000 --- a/src/org/traccar/protocol/MtxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class MtxProtocol extends BaseProtocol { - - public MtxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MtxProtocolDecoder(MtxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MtxProtocolDecoder.java b/src/org/traccar/protocol/MtxProtocolDecoder.java deleted file mode 100644 index d1207bedf..000000000 --- a/src/org/traccar/protocol/MtxProtocolDecoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class MtxProtocolDecoder extends BaseProtocolDecoder { - - public MtxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("#MTX,") - .number("(d+),") // imei - .number("(dddd)(dd)(dd),") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+.?d*),") // odometer - .groupBegin() - .number("d+") - .or() - .text("X") - .groupEnd() - .text(",") - .expression("(?:[01]|X),") - .expression("([01]+),") // input - .expression("([01]+),") // output - .number("(d+),") // adc1 - .number("(d+)") // adc2 - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("#ACK", remoteAddress)); - } - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setValid(true); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/MxtFrameDecoder.java b/src/org/traccar/protocol/MxtFrameDecoder.java deleted file mode 100644 index d70e92da1..000000000 --- a/src/org/traccar/protocol/MxtFrameDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class MxtFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 2) { - return null; - } - - int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0x04); - if (index != -1) { - ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); - - while (buf.readerIndex() <= index) { - int b = buf.readUnsignedByte(); - if (b == 0x10) { - result.writeByte(buf.readUnsignedByte() - 0x20); - } else { - result.writeByte(b); - } - } - - return result; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/MxtProtocol.java b/src/org/traccar/protocol/MxtProtocol.java deleted file mode 100644 index dbe43fe45..000000000 --- a/src/org/traccar/protocol/MxtProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class MxtProtocol extends BaseProtocol { - - public MxtProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MxtFrameDecoder()); - pipeline.addLast(new MxtProtocolDecoder(MxtProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java deleted file mode 100644 index 7bde85f87..000000000 --- a/src/org/traccar/protocol/MxtProtocolDecoder.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class MxtProtocolDecoder extends BaseProtocolDecoder { - - public MxtProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_ACK = 0x02; - public static final int MSG_NACK = 0x03; - public static final int MSG_POSITION = 0x31; - - private static void sendResponse(Channel channel, int device, long id, int crc) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(device); - response.writeByte(MSG_ACK); - response.writeIntLE((int) id); - response.writeShortLE(crc); - response.writeShortLE(Checksum.crc16( - Checksum.CRC16_XMODEM, response.nioBuffer())); - - ByteBuf encoded = Unpooled.buffer(); - encoded.writeByte(0x01); // header - while (response.isReadable()) { - int b = response.readByte(); - if (b == 0x01 || b == 0x04 || b == 0x10 || b == 0x11 || b == 0x13) { - encoded.writeByte(0x10); - b += 0x20; - } - encoded.writeByte(b); - } - response.release(); - encoded.writeByte(0x04); // ending - channel.writeAndFlush(new NetworkMessage(encoded, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // start - int device = buf.readUnsignedByte(); // device descriptor - int type = buf.readUnsignedByte(); - - long id = buf.readUnsignedIntLE(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); - if (deviceSession == null) { - return null; - } - - if (type == MSG_POSITION) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // protocol - int infoGroups = buf.readUnsignedByte(); - - position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); - - DateBuilder dateBuilder = new DateBuilder().setDate(2000, 1, 1); - - long date = buf.readUnsignedIntLE(); - - long days = BitUtil.from(date, 6 + 6 + 5); - long hours = BitUtil.between(date, 6 + 6, 6 + 6 + 5); - long minutes = BitUtil.between(date, 6, 6 + 6); - long seconds = BitUtil.to(date, 6); - - dateBuilder.addMillis((((days * 24 + hours) * 60 + minutes) * 60 + seconds) * 1000); - - position.setTime(dateBuilder.getDate()); - - position.setValid(true); - position.setLatitude(buf.readIntLE() / 1000000.0); - position.setLongitude(buf.readIntLE() / 1000000.0); - - 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); - } - 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.set(Position.KEY_CHARGE, BitUtil.check(flags, 20)); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - buf.readUnsignedByte(); // input mask - - if (BitUtil.check(infoGroups, 0)) { - buf.skipBytes(8); // waypoints - } - - if (BitUtil.check(infoGroups, 1)) { - buf.skipBytes(8); // wireless accessory - } - - if (BitUtil.check(infoGroups, 2)) { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_HDOP, buf.readUnsignedByte()); - position.setAccuracy(buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - 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.readUnsignedIntLE()); - } - - if (BitUtil.check(infoGroups, 4)) { - position.set(Position.KEY_HOURS, UnitsConverter.msFromMinutes(buf.readUnsignedIntLE())); - } - - if (BitUtil.check(infoGroups, 5)) { - buf.readUnsignedIntLE(); // reason - } - - if (BitUtil.check(infoGroups, 6)) { - 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.readUnsignedIntLE())); - } - - buf.readerIndex(buf.writerIndex() - 3); - sendResponse(channel, device, id, buf.readUnsignedShortLE()); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NavigilFrameDecoder.java b/src/org/traccar/protocol/NavigilFrameDecoder.java deleted file mode 100644 index e8b6bea52..000000000 --- a/src/org/traccar/protocol/NavigilFrameDecoder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - * 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 NavigilFrameDecoder extends BaseFrameDecoder { - - private static final int MESSAGE_HEADER = 20; - private static final long PREAMBLE = 0x2477F5F6; - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - // Check minimum length - if (buf.readableBytes() < MESSAGE_HEADER) { - return null; - } - - // Check for preamble - boolean hasPreamble = false; - if (buf.getUnsignedIntLE(buf.readerIndex()) == PREAMBLE) { - hasPreamble = true; - } - - // Check length and return buffer - int length = buf.getUnsignedShortLE(buf.readerIndex() + 6); - if (buf.readableBytes() >= length) { - if (hasPreamble) { - buf.readUnsignedIntLE(); - length -= 4; - } - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NavigilProtocol.java b/src/org/traccar/protocol/NavigilProtocol.java deleted file mode 100644 index 2c946c39f..000000000 --- a/src/org/traccar/protocol/NavigilProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class NavigilProtocol extends BaseProtocol { - - public NavigilProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NavigilFrameDecoder()); - pipeline.addLast(new NavigilProtocolDecoder(NavigilProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/NavigilProtocolDecoder.java b/src/org/traccar/protocol/NavigilProtocolDecoder.java deleted file mode 100644 index db5521201..000000000 --- a/src/org/traccar/protocol/NavigilProtocolDecoder.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Checksum; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.Date; - -public class NavigilProtocolDecoder extends BaseProtocolDecoder { - - public NavigilProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final int LEAP_SECONDS_DELTA = 25; - - public static final int MSG_ERROR = 2; - public static final int MSG_INDICATION = 4; - public static final int MSG_CONN_OPEN = 5; - public static final int MSG_CONN_CLOSE = 6; - public static final int MSG_SYSTEM_REPORT = 7; - public static final int MSG_UNIT_REPORT = 8; - public static final int MSG_GEOFENCE_ALARM = 10; - public static final int MSG_INPUT_ALARM = 11; - public static final int MSG_TG2_REPORT = 12; - public static final int MSG_POSITION_REPORT = 13; - public static final int MSG_POSITION_REPORT_2 = 15; - public static final int MSG_SNAPSHOT4 = 17; - public static final int MSG_TRACKING_DATA = 18; - public static final int MSG_MOTION_ALARM = 19; - public static final int MSG_ACKNOWLEDGEMENT = 255; - - private static Date convertTimestamp(long timestamp) { - return new Date((timestamp - LEAP_SECONDS_DELTA) * 1000); - } - - private int senderSequenceNumber = 1; - - private void sendAcknowledgment(Channel channel, int sequenceNumber) { - ByteBuf data = Unpooled.buffer(4); - data.writeShortLE(sequenceNumber); - data.writeShortLE(0); // OK - - ByteBuf header = Unpooled.buffer(20); - header.writeByte(1); header.writeByte(0); - 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.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(header, data), channel.remoteAddress())); - } - } - - private Position parseUnitReport( - 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.readUnsignedShortLE(); // report trigger - position.set(Position.KEY_FLAGS, buf.readUnsignedShortLE()); - - position.setLatitude(buf.readIntLE() * 0.0000001); - position.setLongitude(buf.readIntLE() * 0.0000001); - position.setAltitude(buf.readUnsignedShortLE()); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedShortLE()); - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedShortLE()); - position.set("gpsAntennaState", buf.readUnsignedShortLE()); - - position.setSpeed(buf.readUnsignedShortLE() * 0.194384); - position.setCourse(buf.readUnsignedShortLE()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - position.set(Position.KEY_DISTANCE, buf.readUnsignedIntLE()); - - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - - position.set(Position.KEY_CHARGE, buf.readUnsignedShortLE()); - - position.setTime(convertTimestamp(buf.readUnsignedIntLE())); - - return position; - } - - private Position parseTg2Report( - 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.readUnsignedShortLE(); // report trigger - buf.readUnsignedByte(); // reserved - buf.readUnsignedByte(); // assisted GPS age - - position.setTime(convertTimestamp(buf.readUnsignedIntLE())); - - 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.readUnsignedShortLE() * 0.194384); - position.setCourse(buf.readUnsignedShortLE()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - position.set("maximumSpeed", buf.readUnsignedShortLE()); - position.set("minimumSpeed", buf.readUnsignedShortLE()); - - 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.readUnsignedShortLE() * 0.001); - - return position; - } - - private Position parsePositionReport( - 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.readMediumLE() * 0.00002); - position.setLongitude(buf.readMediumLE() * 0.00002); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedByte() * 2); - - short flags = buf.readUnsignedByte(); - position.setValid((flags & 0x80) == 0x80 && (flags & 0x40) == 0x40); - - buf.readUnsignedByte(); // reserved - - return position; - } - - private Position parsePositionReport2( - 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.readIntLE() * 0.0000001); - position.setLongitude(buf.readIntLE() * 0.0000001); - - buf.readUnsignedByte(); // report trigger - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - short flags = buf.readUnsignedByte(); - position.setValid((flags & 0x80) == 0x80 && (flags & 0x40) == 0x40); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - - return position; - } - - private Position parseSnapshot4( - DeviceSession deviceSession, ByteBuf buf, int sequenceNumber) { - Position position = new Position(getProtocolName()); - - position.set(Position.KEY_INDEX, sequenceNumber); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // report trigger - buf.readUnsignedByte(); // position fix source - buf.readUnsignedByte(); // GNSS fix quality - buf.readUnsignedByte(); // GNSS assistance age - - long flags = buf.readUnsignedIntLE(); - position.setValid((flags & 0x0400) == 0x0400); - - position.setTime(convertTimestamp(buf.readUnsignedIntLE())); - - 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.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.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.readUnsignedShortLE() * 0.001); - - return position; - } - - private Position parseTrackingData( - 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)); - - buf.readUnsignedByte(); // tracking mode - - short flags = buf.readUnsignedByte(); - position.setValid((flags & 0x01) == 0x01); - - buf.readUnsignedShortLE(); // duration - - 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.readUnsignedShortLE() * 0.001); - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // protocol version - buf.readUnsignedByte(); // version id - 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.readUnsignedIntLE())); - if (deviceSession == null) { - return null; - } - - long timestamp = buf.readUnsignedIntLE(); - - if ((flags & 0x1) == 0x0) { - sendAcknowledgment(channel, sequenceNumber); - } - - switch (messageId) { - case MSG_UNIT_REPORT: - return parseUnitReport(deviceSession, buf, sequenceNumber); - case MSG_TG2_REPORT: - return parseTg2Report(deviceSession, buf, sequenceNumber); - case MSG_POSITION_REPORT: - return parsePositionReport(deviceSession, buf, sequenceNumber, timestamp); - case MSG_POSITION_REPORT_2: - return parsePositionReport2(deviceSession, buf, sequenceNumber, timestamp); - case MSG_SNAPSHOT4: - return parseSnapshot4(deviceSession, buf, sequenceNumber); - case MSG_TRACKING_DATA: - return parseTrackingData(deviceSession, buf, sequenceNumber, timestamp); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/NavisFrameDecoder.java b/src/org/traccar/protocol/NavisFrameDecoder.java deleted file mode 100644 index 8a0bb0b9a..000000000 --- a/src/org/traccar/protocol/NavisFrameDecoder.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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 java.nio.charset.StandardCharsets; -import org.traccar.BaseFrameDecoder; -import org.traccar.BasePipelineFactory; - -public class NavisFrameDecoder extends BaseFrameDecoder { - - private static final int NTCB_HEADER_LENGTH = 16; - private static final int NTCB_LENGTH_OFFSET = 12; - private static final int FLEX_HEADER_LENGTH = 2; - - private int flexDataSize; - - public void setFlexDataSize(int flexDataSize) { - this.flexDataSize = flexDataSize; - } - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.getByte(buf.readerIndex()) == 0x7F) { - return buf.readRetainedSlice(1); // keep alive - } - - if (ctx != null && flexDataSize == 0) { - NavisProtocolDecoder protocolDecoder = - BasePipelineFactory.getHandler(ctx.pipeline(), NavisProtocolDecoder.class); - if (protocolDecoder != null) { - flexDataSize = protocolDecoder.getFlexDataSize(); - } - } - - if (flexDataSize > 0) { - - if (buf.readableBytes() > FLEX_HEADER_LENGTH) { - int length = 0; - String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII); - switch (type) { - // FLEX 1.0 - case "~A": - length = flexDataSize * buf.getByte(buf.readerIndex() + FLEX_HEADER_LENGTH) + 1 + 1; - break; - case "~T": - length = flexDataSize + 4 + 1; - break; - case "~C": - length = flexDataSize + 1; - break; - // FLEX 2.0 (Extra packages) - case "~E": - length++; - for (int i = 0; i < buf.getByte(buf.readerIndex() + FLEX_HEADER_LENGTH); i++) { - if (buf.readableBytes() > FLEX_HEADER_LENGTH + length + 1) { - length += buf.getUnsignedShort(length + FLEX_HEADER_LENGTH) + 2; - } else { - return null; - } - } - length++; - break; - case "~X": - length = buf.getUnsignedShortLE(buf.readerIndex() + FLEX_HEADER_LENGTH) + 4 + 1; - break; - default: - return null; - } - - if (buf.readableBytes() >= FLEX_HEADER_LENGTH + length) { - return buf.readRetainedSlice(buf.readableBytes()); - } - } - - } else { - - if (buf.readableBytes() < NTCB_HEADER_LENGTH) { - return null; - } - - int length = NTCB_HEADER_LENGTH + buf.getUnsignedShortLE(buf.readerIndex() + NTCB_LENGTH_OFFSET); - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NavisProtocol.java b/src/org/traccar/protocol/NavisProtocol.java deleted file mode 100644 index d5af6838d..000000000 --- a/src/org/traccar/protocol/NavisProtocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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; - -public class NavisProtocol extends BaseProtocol { - - public NavisProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NavisFrameDecoder()); - pipeline.addLast(new NavisProtocolDecoder(NavisProtocol.this)); - } - }); - } -} diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java deleted file mode 100644 index 7ba474ae0..000000000 --- a/src/org/traccar/protocol/NavisProtocolDecoder.java +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.Checksum.Algorithm; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -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.Date; - -public class NavisProtocolDecoder extends BaseProtocolDecoder { - - private static final int[] FLEX_FIELDS_SIZES = { - 4, 2, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 4, 4, 2, 2, - 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 4, 2, 2, 2, 2, 2, 1, 1, 1, 2, 4, 2, 1, - /* FLEX 2.0 */ - 8, 2, 1, 16, 4, 2, 4, 37, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 12, 24, 48, 1, 1, 1, 1, 4, 4, - 1, 4, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1 - }; - - private String prefix; - private long deviceUniqueId, serverId; - private int flexDataSize; - private int flexBitFieldSize; - private final byte[] flexBitField = new byte[16]; - - public NavisProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int F10 = 0x01; - public static final int F20 = 0x02; - public static final int F30 = 0x03; - public static final int F40 = 0x04; - public static final int F50 = 0x05; - public static final int F51 = 0x15; - public static final int F52 = 0x25; - public static final int F60 = 0x06; - - public int getFlexDataSize() { - return flexDataSize; - } - - private static boolean isFormat(int type, int... types) { - for (int i : types) { - if (type == i) { - return true; - } - } - return false; - } - - private Position parseNtcbPosition(DeviceSession deviceSession, ByteBuf buf) { - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - - int format; - if (buf.getUnsignedByte(buf.readerIndex()) == 0) { - format = buf.readUnsignedShortLE(); - } else { - format = buf.readUnsignedByte(); - } - position.set("format", format); - - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - - buf.skipBytes(6); // event time - - short armedStatus = buf.readUnsignedByte(); - if (isFormat(format, F10, F20, F30, F40, F50, F51, F52)) { - position.set(Position.KEY_ARMED, BitUtil.to(armedStatus, 7)); - if (BitUtil.check(armedStatus, 7)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - } else if (isFormat(format, F60)) { - position.set(Position.KEY_ARMED, BitUtil.check(armedStatus, 0)); - if (BitUtil.check(armedStatus, 1)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - } - - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - if (isFormat(format, F10, F20, F30)) { - int output = buf.readUnsignedShortLE(); - position.set(Position.KEY_OUTPUT, output); - for (int i = 0; i < 16; i++) { - position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(output, i)); - } - } else if (isFormat(format, F50, F51, F52)) { - short extField = buf.readUnsignedByte(); - position.set(Position.KEY_OUTPUT, BitUtil.to(extField, 2)); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(extField, 0)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(extField, 1)); - position.set(Position.KEY_SATELLITES, BitUtil.from(extField, 2)); - } else if (isFormat(format, F40, F60)) { - short output = buf.readUnsignedByte(); - position.set(Position.KEY_OUTPUT, BitUtil.to(output, 4)); - for (int i = 0; i < 4; i++) { - position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(output, i)); - } - } - - if (isFormat(format, F10, F20, F30, F40)) { - int input = buf.readUnsignedShortLE(); - position.set(Position.KEY_INPUT, input); - if (!isFormat(format, F40)) { - for (int i = 0; i < 16; i++) { - position.set(Position.PREFIX_IN + (i + 1), BitUtil.check(input, i)); - } - } else { - position.set(Position.PREFIX_IN + 1, BitUtil.check(input, 0)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(input, 1)); - position.set(Position.PREFIX_IN + 3, BitUtil.check(input, 2)); - position.set(Position.PREFIX_IN + 4, BitUtil.check(input, 3)); - position.set(Position.PREFIX_IN + 5, BitUtil.between(input, 4, 7)); - position.set(Position.PREFIX_IN + 6, BitUtil.between(input, 7, 10)); - position.set(Position.PREFIX_IN + 7, BitUtil.between(input, 10, 12)); - position.set(Position.PREFIX_IN + 8, BitUtil.between(input, 12, 14)); - } - } else if (isFormat(format, F50, F51, F52, F60)) { - short input = buf.readUnsignedByte(); - position.set(Position.KEY_INPUT, input); - for (int i = 0; i < 8; i++) { - position.set(Position.PREFIX_IN + (i + 1), BitUtil.check(input, i)); - } - } - - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - - if (isFormat(format, F10, F20, F30)) { - position.set(Position.PREFIX_TEMP + 1, buf.readShortLE()); - } - - if (isFormat(format, F10, F20, F50, F51, F52, F60)) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); - } - if (isFormat(format, F60)) { - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE()); - } - - // Impulse counters - if (isFormat(format, F20, F50, F51, F52, F60)) { - buf.readUnsignedIntLE(); - buf.readUnsignedIntLE(); - } - - if (isFormat(format, F60)) { - // Fuel - buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - position.set(Position.PREFIX_TEMP + 2, buf.readByte()); - position.set(Position.PREFIX_TEMP + 3, buf.readByte()); - position.set(Position.PREFIX_TEMP + 4, buf.readByte()); - position.set(Position.KEY_AXLE_WEIGHT, buf.readIntLE()); - position.set(Position.KEY_RPM, buf.readUnsignedShortLE()); - } - - if (isFormat(format, F20, F50, F51, F52, F60)) { - int navSensorState = buf.readUnsignedByte(); - position.setValid(BitUtil.check(navSensorState, 1)); - if (isFormat(format, F60)) { - position.set(Position.KEY_SATELLITES, BitUtil.from(navSensorState, 2)); - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte() + 1, buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - if (isFormat(format, F60)) { - position.setLatitude(buf.readIntLE() / 600000.0); - position.setLongitude(buf.readIntLE() / 600000.0); - position.setAltitude(buf.readIntLE() * 0.1); - } else { - 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.readFloatLE() * 1000); - position.set(Position.KEY_DISTANCE, buf.readFloatLE() * 1000); - - // Segment times - buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); - } - - // Other - if (isFormat(format, F51, F52)) { - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); - buf.readByte(); - buf.readUnsignedShortLE(); - } - - // Four temperature sensors - if (isFormat(format, F40, F52)) { - position.set(Position.PREFIX_TEMP + 1, buf.readByte()); - position.set(Position.PREFIX_TEMP + 2, buf.readByte()); - position.set(Position.PREFIX_TEMP + 3, buf.readByte()); - position.set(Position.PREFIX_TEMP + 4, buf.readByte()); - } - - return position; - } - - private Object processNtcbSingle(DeviceSession deviceSession, Channel channel, ByteBuf buf) { - Position position = parseNtcbPosition(deviceSession, buf); - - ByteBuf response = Unpooled.buffer(7); - response.writeCharSequence("*<T", StandardCharsets.US_ASCII); - response.writeIntLE((int) position.getLong(Position.KEY_INDEX)); - sendNtcbReply(channel, response); - - return position.getFixTime() != null ? position : null; - } - - private Object processNtcbArray(DeviceSession deviceSession, Channel channel, ByteBuf buf) { - List<Position> positions = new LinkedList<>(); - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - Position position = parseNtcbPosition(deviceSession, buf); - if (position.getFixTime() != null) { - positions.add(position); - } - } - - ByteBuf response = Unpooled.buffer(7); - response.writeCharSequence("*<A", StandardCharsets.US_ASCII); - response.writeByte(count); - sendNtcbReply(channel, response); - - if (positions.isEmpty()) { - return null; - } - - return positions; - } - - private boolean checkFlexBitfield(int index) { - int byteIndex = Math.floorDiv(index, 8); - int bitIndex = Math.floorMod(index, 8); - return BitUtil.check(flexBitField[byteIndex], 7 - bitIndex); - } - - private Position parseFlexPosition(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - - int status = 0; - short input = 0; - short output = 0; - - for (int i = 0; i < flexBitFieldSize; i++) { - if (!checkFlexBitfield(i)) { - continue; - } - - switch (i) { - case 0: - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - break; - case 1: - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - break; - case 3: - short armedStatus = buf.readUnsignedByte(); - position.set(Position.KEY_ARMED, BitUtil.check(armedStatus, 0)); - if (BitUtil.check(armedStatus, 1)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - break; - case 4: - status = buf.readUnsignedByte(); - position.set(Position.KEY_STATUS, status); - break; - case 5: - int status2 = buf.readUnsignedByte(); - position.set(Position.KEY_STATUS, (short) (BitUtil.to(status, 8) | (status2 << 8))); - break; - case 6: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 7: - int navSensorState = buf.readUnsignedByte(); - position.setValid(BitUtil.check(navSensorState, 1)); - position.set(Position.KEY_SATELLITES, BitUtil.from(navSensorState, 2)); - break; - case 8: - position.setTime(new DateBuilder(new Date(buf.readUnsignedIntLE() * 1000)).getDate()); - break; - case 9: - position.setLatitude(buf.readIntLE() / 600000.0); - break; - case 10: - position.setLongitude(buf.readIntLE() / 600000.0); - break; - case 11: - position.setAltitude(buf.readIntLE() * 0.1); - break; - case 12: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); - break; - case 13: - position.setCourse(buf.readUnsignedShortLE()); - break; - case 14: - position.set(Position.KEY_ODOMETER, buf.readFloatLE() * 1000); - break; - case 15: - position.set(Position.KEY_DISTANCE, buf.readFloatLE() * 1000); - break; - case 18: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - break; - case 19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - break; - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - position.set(Position.PREFIX_ADC + (i - 19), buf.readUnsignedShortLE()); - break; - case 28: - input = buf.readUnsignedByte(); - position.set(Position.KEY_INPUT, input); - for (int k = 0; k < 8; k++) { - position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(input, k)); - } - break; - case 29: - short input2 = buf.readUnsignedByte(); - position.set(Position.KEY_INPUT, (short) (BitUtil.to(input, 8) | (input2 << 8))); - for (int k = 0; k < 8; k++) { - position.set(Position.PREFIX_IN + (k + 9), BitUtil.check(input2, k)); - } - break; - case 30: - output = buf.readUnsignedByte(); - position.set(Position.KEY_OUTPUT, output); - for (int k = 0; k < 8; k++) { - position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(output, k)); - } - break; - case 31: - short output2 = buf.readUnsignedByte(); - position.set(Position.KEY_OUTPUT, (short) (BitUtil.to(output, 8) | (output2 << 8))); - for (int k = 0; k < 8; k++) { - position.set(Position.PREFIX_OUT + (k + 9), BitUtil.check(output2, k)); - } - break; - case 36: - position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); - break; - case 44: - case 45: - case 46: - case 47: - case 48: - case 49: - case 50: - case 51: - position.set(Position.PREFIX_TEMP + (i - 43), buf.readByte()); - break; - case 68: - position.set("can-speed", buf.readUnsignedByte()); - break; - // FLEX 2.0 - case 69: - int satVisible = 0; - for (int k = 0; k < 8; k++) { - satVisible += buf.readUnsignedByte(); - } - position.set(Position.KEY_SATELLITES_VISIBLE, satVisible); - break; - case 70: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); - break; - default: - if (i < FLEX_FIELDS_SIZES.length) { - buf.skipBytes(FLEX_FIELDS_SIZES[i]); - } - break; - } - } - - return position; - } - - private Position parseFlex20Position(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int length = buf.readUnsignedShort(); - if (length <= buf.readableBytes() && buf.readUnsignedByte() == 0x0A) { - - buf.readUnsignedByte(); // length of static part - - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - buf.readUnsignedInt(); // event time - - int navSensorState = buf.readUnsignedByte(); - position.setValid(BitUtil.check(navSensorState, 1)); - position.set(Position.KEY_SATELLITES, BitUtil.from(navSensorState, 2)); - - position.setTime(new DateBuilder(new Date(buf.readUnsignedIntLE() * 1000)).getDate()); - position.setLatitude(buf.readIntLE() / 600000.0); - position.setLongitude(buf.readIntLE() / 600000.0); - position.setAltitude(buf.readIntLE() * 0.1); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); - position.setCourse(buf.readUnsignedShortLE()); - position.set(Position.KEY_ODOMETER, buf.readFloatLE() * 1000); - - buf.skipBytes(length - buf.readerIndex() - 1); // skip unused part - } - - return position; - } - - private interface FlexPositionParser { - Position parsePosition(DeviceSession deviceSession, ByteBuf buf); - } - - private Object processFlexSingle( - FlexPositionParser parser, String flexHeader, DeviceSession deviceSession, Channel channel, ByteBuf buf) { - - if (!flexHeader.equals("~C")) { - buf.readUnsignedInt(); // event index - } - - Position position = parser.parsePosition(deviceSession, buf); - - ByteBuf response = Unpooled.buffer(); - response.writeCharSequence(flexHeader, StandardCharsets.US_ASCII); - response.writeIntLE((int) position.getLong(Position.KEY_INDEX)); - sendFlexReply(channel, response); - - return position.getFixTime() != null ? position : null; - } - - private Object processFlexArray( - FlexPositionParser parser, String flexHeader, DeviceSession deviceSession, Channel channel, ByteBuf buf) { - - List<Position> positions = new LinkedList<>(); - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - Position position = parser.parsePosition(deviceSession, buf); - if (position.getFixTime() != null) { - positions.add(position); - } - } - - ByteBuf response = Unpooled.buffer(); - response.writeCharSequence(flexHeader, StandardCharsets.US_ASCII); - response.writeByte(count); - sendFlexReply(channel, response); - - return !positions.isEmpty() ? positions : null; - } - - private Object processFlexNegotiation(Channel channel, ByteBuf buf) { - if ((byte) buf.readUnsignedByte() != (byte) 0xB0) { - return null; - } - - short flexProtocolVersion = buf.readUnsignedByte(); - short flexStructVersion = buf.readUnsignedByte(); - if ((flexProtocolVersion == 0x0A || flexProtocolVersion == 0x14) - && (flexStructVersion == 0x0A || flexStructVersion == 0x14)) { - - flexBitFieldSize = buf.readUnsignedByte(); - if (flexBitFieldSize > 122) { - return null; - } - - buf.readBytes(flexBitField, 0, (int) Math.ceil((double) flexBitFieldSize / 8)); - - flexDataSize = 0; - for (int i = 0; i < flexBitFieldSize; i++) { - if (checkFlexBitfield(i)) { - flexDataSize += FLEX_FIELDS_SIZES[i]; - } - } - } else { - flexProtocolVersion = 0x14; - flexStructVersion = 0x14; - } - - ByteBuf response = Unpooled.buffer(9); - response.writeCharSequence("*<FLEX", StandardCharsets.US_ASCII); - response.writeByte(0xB0); - response.writeByte(flexProtocolVersion); - response.writeByte(flexStructVersion); - sendNtcbReply(channel, response); - - return null; - } - - private Object processHandshake(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - buf.readByte(); // colon - if (getDeviceSession(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)) != null) { - sendNtcbReply(channel, Unpooled.copiedBuffer("*<S", StandardCharsets.US_ASCII)); - } - return null; - } - - private void sendNtcbReply(Channel channel, ByteBuf data) { - if (channel != null) { - 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.xor(data.nioBuffer())); - header.writeByte(Checksum.xor(header.nioBuffer())); - - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(header, data), channel.remoteAddress())); - } - } - - private void sendFlexReply(Channel channel, ByteBuf data) { - if (channel != null) { - ByteBuf cs = Unpooled.buffer(1); - cs.writeByte(Checksum.crc8(new Algorithm(8, 0x31, 0xFF, false, false, 0x00), data.nioBuffer())); - - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(data, cs), channel.remoteAddress())); - } - } - - private Object decodeNtcb(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - prefix = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); - buf.skipBytes(prefix.length()); // prefix @NTC by default - serverId = buf.readUnsignedIntLE(); - deviceUniqueId = buf.readUnsignedIntLE(); - int length = buf.readUnsignedShortLE(); - buf.skipBytes(2); // header and data XOR checksum - - if (length == 0) { - return null; // keep alive message - } - - String type = buf.toString(buf.readerIndex(), 3, StandardCharsets.US_ASCII); - buf.skipBytes(type.length()); - - if (type.equals("*>S")) { - return processHandshake(channel, remoteAddress, buf); - } else { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - switch (type) { - case "*>A": - return processNtcbArray(deviceSession, channel, buf); - case "*>T": - return processNtcbSingle(deviceSession, channel, buf); - case "*>F": - buf.skipBytes(3); - return processFlexNegotiation(channel, buf); - default: - break; - } - } - } - - return null; - } - - private Object decodeFlex(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - if (buf.getByte(buf.readerIndex()) == 0x7F) { - return null; // keep alive - } - - String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII); - buf.skipBytes(type.length()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - switch (type) { - // FLEX 1.0 - case "~A": - return processFlexArray(this::parseFlexPosition, type, deviceSession, channel, buf); - case "~T": - case "~C": - return processFlexSingle(this::parseFlexPosition, type, deviceSession, channel, buf); - // FLEX 2.0 (extra packages) - case "~E": - return processFlexArray(this::parseFlex20Position, type, deviceSession, channel, buf); - case "~X": - return processFlexSingle(this::parseFlex20Position, type, deviceSession, channel, buf); - default: - break; - } - } - - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (flexDataSize > 0) { - return decodeFlex(channel, remoteAddress, buf); - } else { - return decodeNtcb(channel, remoteAddress, buf); - } - } - -} diff --git a/src/org/traccar/protocol/NeosProtocol.java b/src/org/traccar/protocol/NeosProtocol.java deleted file mode 100644 index e545a9969..000000000 --- a/src/org/traccar/protocol/NeosProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class NeosProtocol extends BaseProtocol { - - public NeosProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new NeosProtocolDecoder(NeosProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/NeosProtocolDecoder.java b/src/org/traccar/protocol/NeosProtocolDecoder.java deleted file mode 100644 index 6b5596dba..000000000 --- a/src/org/traccar/protocol/NeosProtocolDecoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class NeosProtocolDecoder extends BaseProtocolDecoder { - - public NeosProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text(">") - .number("(d{8}),") // id - .number("d+,") // status - .number("([01]),") // valid - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([EW])") - .number("(d+)(dd.d+),") // longitude - .expression("([NS])") - .number("(d+)(dd.d+),") // latitude - .expression("[^,]*,") // response - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // rssi - .expression("[^,]*,") // event data - .number("(d+)-") // adc - .number("(d+),") // battery - .number("0,") - .number("d,") - .number("([01]{8})") // input - .text("*") - .number("xx!") - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("$OK!", 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.setValid(parser.nextInt() > 0); - position.setTime(parser.nextDateTime()); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setSpeed(parser.nextInt()); - position.setCourse(parser.nextInt()); - - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextInt()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_INPUT, parser.nextBinInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/NoranProtocol.java b/src/org/traccar/protocol/NoranProtocol.java deleted file mode 100644 index 9f3078d6d..000000000 --- a/src/org/traccar/protocol/NoranProtocol.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class NoranProtocol extends BaseProtocol { - - public NoranProtocol() { - setSupportedDataCommands( - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_POSITION_STOP, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NoranProtocolEncoder()); - pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/NoranProtocolDecoder.java b/src/org/traccar/protocol/NoranProtocolDecoder.java deleted file mode 100644 index 53dae7fd6..000000000 --- a/src/org/traccar/protocol/NoranProtocolDecoder.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -public class NoranProtocolDecoder extends BaseProtocolDecoder { - - public NoranProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_UPLOAD_POSITION = 0x0008; - public static final int MSG_UPLOAD_POSITION_NEW = 0x0032; - public static final int MSG_CONTROL = 0x0002; - public static final int MSG_CONTROL_RESPONSE = 0x8009; - public static final int MSG_ALARM = 0x0003; - public static final int MSG_SHAKE_HAND = 0x0000; - public static final int MSG_SHAKE_HAND_RESPONSE = 0x8000; - public static final int MSG_IMAGE_SIZE = 0x0200; - public static final int MSG_IMAGE_PACKET = 0x0201; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedShortLE(); // length - int type = buf.readUnsignedShortLE(); - - if (type == MSG_SHAKE_HAND && channel != null) { - - ByteBuf response = Unpooled.buffer(13); - response.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII); - response.writeByte(0); - response.writeShortLE(response.capacity()); - response.writeShortLE(MSG_SHAKE_HAND_RESPONSE); - response.writeByte(1); // status - response.writeCharSequence("\r\n", StandardCharsets.US_ASCII); - - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - - } else if (type == MSG_UPLOAD_POSITION || type == MSG_UPLOAD_POSITION_NEW - || type == MSG_CONTROL_RESPONSE || type == MSG_ALARM) { - - boolean newFormat = false; - if (type == MSG_UPLOAD_POSITION && buf.readableBytes() == 48 - || type == MSG_ALARM && buf.readableBytes() == 48 - || type == MSG_CONTROL_RESPONSE && buf.readableBytes() == 57) { - newFormat = true; - } - - Position position = new Position(getProtocolName()); - - if (type == MSG_CONTROL_RESPONSE) { - buf.readUnsignedIntLE(); // GIS ip - buf.readUnsignedIntLE(); // GIS port - } - - position.setValid(BitUtil.check(buf.readUnsignedByte(), 0)); - - short alarm = buf.readUnsignedByte(); - switch (alarm) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); - break; - case 9: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - default: - break; - } - - if (newFormat) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedIntLE())); - position.setCourse(buf.readFloatLE()); - } else { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedShortLE()); - } - position.setLongitude(buf.readFloatLE()); - position.setLatitude(buf.readFloatLE()); - - if (!newFormat) { - long timeValue = buf.readUnsignedIntLE(); - DateBuilder dateBuilder = new DateBuilder() - .setYear((int) BitUtil.from(timeValue, 26)) - .setMonth((int) BitUtil.between(timeValue, 22, 26)) - .setDay((int) BitUtil.between(timeValue, 17, 22)) - .setHour((int) BitUtil.between(timeValue, 12, 17)) - .setMinute((int) BitUtil.between(timeValue, 6, 12)) - .setSecond((int) BitUtil.to(timeValue, 6)); - position.setTime(dateBuilder.getDate()); - } - - ByteBuf rawId; - if (newFormat) { - rawId = buf.readSlice(12); - } else { - rawId = buf.readSlice(11); - } - String id = rawId.toString(StandardCharsets.US_ASCII).replaceAll("[^\\p{Print}]", ""); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - if (newFormat) { - DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); - position.setTime(dateFormat.parse(buf.readSlice(17).toString(StandardCharsets.US_ASCII))); - buf.readByte(); - } - - if (!newFormat) { - 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.readShortLE()); - position.set(Position.KEY_ODOMETER, buf.readFloatLE()); - } - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NoranProtocolEncoder.java b/src/org/traccar/protocol/NoranProtocolEncoder.java deleted file mode 100644 index 92826c8b2..000000000 --- a/src/org/traccar/protocol/NoranProtocolEncoder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class NoranProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(String content) { - - ByteBuf buf = Unpooled.buffer(12 + 56); - - buf.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII); - buf.writeByte(0); - buf.writeShortLE(buf.capacity()); - buf.writeShortLE(NoranProtocolDecoder.MSG_CONTROL); - buf.writeInt(0); // gis ip - buf.writeShortLE(0); // gis port - buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); - buf.writerIndex(buf.writerIndex() + 50 - content.length()); - buf.writeCharSequence("\r\n", StandardCharsets.US_ASCII); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return encodeContent("*KW,000,000,000000#"); - case Command.TYPE_POSITION_PERIODIC: - int interval = command.getInteger(Command.KEY_FREQUENCY); - return encodeContent("*KW,000,002,000000," + interval + "#"); - case Command.TYPE_POSITION_STOP: - return encodeContent("*KW,000,002,000000,0#"); - case Command.TYPE_ENGINE_STOP: - return encodeContent("*KW,000,007,000000,0#"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent("*KW,000,007,000000,1#"); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/NvsFrameDecoder.java b/src/org/traccar/protocol/NvsFrameDecoder.java deleted file mode 100644 index e93a58cf6..000000000 --- a/src/org/traccar/protocol/NvsFrameDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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 NvsFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 4 + 2) { - return null; - } - - int length; - if (buf.getUnsignedByte(buf.readerIndex()) == 0) { - length = 2 + buf.getUnsignedShort(buf.readerIndex()); - } else { - length = 4 + 2 + buf.getUnsignedShort(buf.readerIndex() + 4) + 2; - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NvsProtocol.java b/src/org/traccar/protocol/NvsProtocol.java deleted file mode 100644 index d319b22f3..000000000 --- a/src/org/traccar/protocol/NvsProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class NvsProtocol extends BaseProtocol { - - public NvsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NvsFrameDecoder()); - pipeline.addLast(new NvsProtocolDecoder(NvsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/NvsProtocolDecoder.java b/src/org/traccar/protocol/NvsProtocolDecoder.java deleted file mode 100644 index 5d1159f7d..000000000 --- a/src/org/traccar/protocol/NvsProtocolDecoder.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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. - * 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.Protocol; -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; - -public class NvsProtocolDecoder extends BaseProtocolDecoder { - - public NvsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void sendResponse(Channel channel, SocketAddress remoteAddress, String response) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Unpooled.copiedBuffer(response, StandardCharsets.US_ASCII), remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - - if (buf.getUnsignedByte(buf.readerIndex()) == 0) { - - buf.readUnsignedShort(); // length - - String imei = buf.toString(buf.readerIndex(), 15, StandardCharsets.US_ASCII); - - if (getDeviceSession(channel, remoteAddress, imei) != null) { - sendResponse(channel, remoteAddress, "OK"); - } else { - sendResponse(channel, remoteAddress, "NO01"); - } - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - buf.skipBytes(4); // marker - buf.readUnsignedShort(); // length - buf.readLong(); // imei - buf.readUnsignedByte(); // codec - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - position.set("reason", buf.readUnsignedByte()); - - position.setLongitude(buf.readInt() / 10000000.0); - position.setLatitude(buf.readInt() / 10000000.0); - position.setAltitude(buf.readShort()); - position.setCourse(buf.readUnsignedShort()); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - position.setValid(buf.readUnsignedByte() != 0); - - buf.readUnsignedByte(); // used systems - - buf.readUnsignedByte(); // cause element id - - // Read 1 byte data - int cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedByte()); - } - - // Read 2 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedShort()); - } - - // Read 4 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedInt()); - } - - // Read 8 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readLong()); - } - - positions.add(position); - } - - return positions; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/NyitechProtocol.java b/src/org/traccar/protocol/NyitechProtocol.java deleted file mode 100644 index 58974be5c..000000000 --- a/src/org/traccar/protocol/NyitechProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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; - -public class NyitechProtocol extends BaseProtocol { - - public NyitechProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); - pipeline.addLast(new NyitechProtocolDecoder(NyitechProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/NyitechProtocolDecoder.java b/src/org/traccar/protocol/NyitechProtocolDecoder.java deleted file mode 100644 index e145205f7..000000000 --- a/src/org/traccar/protocol/NyitechProtocolDecoder.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.charset.StandardCharsets; - -public class NyitechProtocolDecoder extends BaseProtocolDecoder { - - public NyitechProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final short MSG_LOGIN = 0x1001; - public static final short MSG_COMPREHENSIVE_LIVE = 0x2001; - public static final short MSG_COMPREHENSIVE_HISTORY = 0x2002; - public static final short MSG_ALARM = 0x2003; - public static final short MSG_FIXED = 0x2004; - - private void decodeLocation(Position position, ByteBuf buf) { - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - int flags = buf.readUnsignedByte(); - position.setValid(BitUtil.to(flags, 2) > 0); - - double lat = buf.readUnsignedIntLE() / 3600000.0; - double lon = buf.readUnsignedIntLE() / 3600000.0; - - position.setLatitude(BitUtil.check(flags, 2) ? lat : -lat); - position.setLongitude(BitUtil.check(flags, 3) ? lon : -lon); - - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShortLE())); - position.setCourse(buf.readUnsignedShortLE() * 0.1); - position.setAltitude(buf.readShortLE() * 0.1); - } - - private String decodeAlarm(int type) { - switch (type) { - case 0x09: - return Position.ALARM_ACCELERATION; - case 0x0a: - return Position.ALARM_BRAKING; - case 0x0b: - return Position.ALARM_CORNERING; - case 0x0e: - return Position.ALARM_SOS; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedShortLE(); // length - - String id = buf.readCharSequence(12, StandardCharsets.US_ASCII).toString(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - int type = buf.readUnsignedShortLE(); - - if (type != MSG_LOGIN && type != MSG_COMPREHENSIVE_LIVE - && type != MSG_COMPREHENSIVE_HISTORY && type != MSG_ALARM && type != MSG_FIXED) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (type == MSG_COMPREHENSIVE_LIVE || type == MSG_COMPREHENSIVE_HISTORY) { - buf.skipBytes(6); // time - buf.skipBytes(3); // data - } else if (type == MSG_ALARM) { - buf.readUnsignedShortLE(); // random number - buf.readUnsignedByte(); // tag - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - buf.readUnsignedShortLE(); // threshold - buf.readUnsignedShortLE(); // value - buf.skipBytes(6); // time - } else if (type == MSG_FIXED) { - buf.skipBytes(6); // time - } - - decodeLocation(position, buf); - - return position; - } - -} diff --git a/src/org/traccar/protocol/ObdDongleProtocol.java b/src/org/traccar/protocol/ObdDongleProtocol.java deleted file mode 100644 index 10a55759b..000000000 --- a/src/org/traccar/protocol/ObdDongleProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class ObdDongleProtocol extends BaseProtocol { - - public ObdDongleProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); - pipeline.addLast(new ObdDongleProtocolDecoder(ObdDongleProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/org/traccar/protocol/ObdDongleProtocolDecoder.java deleted file mode 100644 index 1c9771ce9..000000000 --- a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class ObdDongleProtocolDecoder extends BaseProtocolDecoder { - - public ObdDongleProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_TYPE_CONNECT = 0x01; - public static final int MSG_TYPE_CONNACK = 0x02; - public static final int MSG_TYPE_PUBLISH = 0x03; - public static final int MSG_TYPE_PUBACK = 0x04; - public static final int MSG_TYPE_PINGREQ = 0x0C; - 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, ByteBuf content) { - if (channel != null) { - 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.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - int index = buf.readUnsignedShort(); - - String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - int type = buf.readUnsignedByte(); - - buf.readUnsignedShort(); // data length - - if (type == MSG_TYPE_CONNECT) { - - ByteBuf response = Unpooled.buffer(); - response.writeByte(1); - response.writeShort(0); - response.writeInt(0); - sendResponse(channel, MSG_TYPE_CONNACK, index, imei, response); - - } else if (type == MSG_TYPE_PUBLISH) { - - int typeMajor = buf.readUnsignedByte(); - int typeMinor = buf.readUnsignedByte(); - - buf.readUnsignedByte(); // event id - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - int flags = buf.readUnsignedByte(); - - position.setValid(!BitUtil.check(flags, 6)); - - position.set(Position.KEY_SATELLITES, BitUtil.to(flags, 4)); - - double longitude = ((BitUtil.to(buf.readUnsignedShort(), 1) << 24) + buf.readUnsignedMedium()) * 0.00001; - position.setLongitude(BitUtil.check(flags, 5) ? longitude : -longitude); - - double latitude = buf.readUnsignedMedium() * 0.00001; - position.setLatitude(BitUtil.check(flags, 4) ? latitude : -latitude); - - int speedCourse = buf.readUnsignedMedium(); - position.setSpeed(UnitsConverter.knotsFromMph(BitUtil.from(speedCourse, 10) * 0.1)); - position.setCourse(BitUtil.to(speedCourse, 10)); - - ByteBuf response = Unpooled.buffer(); - response.writeByte(typeMajor); - response.writeByte(typeMinor); - sendResponse(channel, MSG_TYPE_PUBACK, index, imei, response); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/OigoProtocol.java b/src/org/traccar/protocol/OigoProtocol.java deleted file mode 100644 index 5056f68aa..000000000 --- a/src/org/traccar/protocol/OigoProtocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * 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; - -public class OigoProtocol extends BaseProtocol { - - public OigoProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java deleted file mode 100644 index b9cc71e8c..000000000 --- a/src/org/traccar/protocol/OigoProtocolDecoder.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.charset.StandardCharsets; - -public class OigoProtocolDecoder extends BaseProtocolDecoder { - - public OigoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_AR_LOCATION = 0x00; - public static final int MSG_AR_REMOTE_START = 0x10; - - public static final int MSG_ACKNOWLEDGEMENT = 0xE0; - - private Position decodeArMessage(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - buf.skipBytes(1); // header - buf.readUnsignedShort(); // length - - int type = buf.readUnsignedByte(); - - int tag = buf.readUnsignedByte(); - - DeviceSession deviceSession; - switch (BitUtil.to(tag, 3)) { - case 0: - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - deviceSession = getDeviceSession(channel, remoteAddress, imei); - break; - case 1: - buf.skipBytes(1); - String meid = buf.readSlice(14).toString(StandardCharsets.US_ASCII); - deviceSession = getDeviceSession(channel, remoteAddress, meid); - break; - default: - deviceSession = getDeviceSession(channel, remoteAddress); - break; - } - - if (deviceSession == null || type != MSG_AR_LOCATION) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - int mask = buf.readInt(); - - if (BitUtil.check(mask, 0)) { - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 1)) { - int date = buf.readUnsignedByte(); - DateBuilder dateBuilder = new DateBuilder() - .setDate(BitUtil.between(date, 4, 8) + 2010, BitUtil.to(date, 4), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - } - - if (BitUtil.check(mask, 2)) { - buf.skipBytes(5); // device time - } - - if (BitUtil.check(mask, 3)) { - position.setLatitude(buf.readUnsignedInt() * 0.000001 - 90); - position.setLongitude(buf.readUnsignedInt() * 0.000001 - 180.0); - } - - if (BitUtil.check(mask, 4)) { - int status = buf.readUnsignedByte(); - position.setValid(BitUtil.between(status, 4, 8) != 0); - position.set(Position.KEY_SATELLITES, BitUtil.to(status, 4)); - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - } - - if (BitUtil.check(mask, 5)) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - } - - if (BitUtil.check(mask, 6)) { - position.setCourse(buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 7)) { - position.setAltitude(buf.readShort()); - } - - if (BitUtil.check(mask, 8)) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } - - if (BitUtil.check(mask, 9)) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - } - - if (BitUtil.check(mask, 10)) { - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - } - - if (BitUtil.check(mask, 11)) { - buf.skipBytes(2); // gpio - } - - if (BitUtil.check(mask, 12)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - } - - if (BitUtil.check(mask, 13)) { - buf.skipBytes(6); // software version - } - - if (BitUtil.check(mask, 14)) { - buf.skipBytes(5); // hardware version - } - - if (BitUtil.check(mask, 15)) { - buf.readUnsignedShort(); // device config - } - - return position; - } - - private double convertCoordinate(long value) { - boolean negative = value < 0; - value = Math.abs(value); - double minutes = (value % 100000) * 0.001; - value /= 100000; - double degrees = value + minutes / 60; - return negative ? -degrees : degrees; - } - - private Position decodeMgMessage(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - buf.readUnsignedByte(); // tag - int flags = buf.getUnsignedByte(buf.readerIndex()); - - DeviceSession deviceSession; - if (BitUtil.check(flags, 6)) { - buf.readUnsignedByte(); // flags - deviceSession = getDeviceSession(channel, remoteAddress); - } else { - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - deviceSession = getDeviceSession(channel, remoteAddress, imei); - } - - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.skipBytes(8); // imsi - - int date = buf.readUnsignedShort(); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(2010 + BitUtil.from(date, 12), BitUtil.between(date, 8, 12), BitUtil.to(date, 8)) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), 0); - - position.setValid(true); - position.setLatitude(convertCoordinate(buf.readInt())); - position.setLongitude(convertCoordinate(buf.readInt())); - - position.setAltitude(UnitsConverter.metersFromFeet(buf.readShort())); - position.setCourse(buf.readUnsignedShort()); - position.setSpeed(UnitsConverter.knotsFromMph(buf.readUnsignedByte())); - - position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); - position.set(Position.PREFIX_IO + 1, buf.readUnsignedByte()); - - dateBuilder.setSecond(buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - int index = buf.readUnsignedByte(); - - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, (long) (buf.readUnsignedInt() * 1609.34)); - - if (channel != null && BitUtil.check(flags, 7)) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(MSG_ACKNOWLEDGEMENT); - response.writeByte(index); - response.writeByte(0x00); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (buf.getUnsignedByte(buf.readerIndex()) == 0x7e) { - return decodeArMessage(channel, remoteAddress, buf); - } else { - return decodeMgMessage(channel, remoteAddress, buf); - } - } - -} diff --git a/src/org/traccar/protocol/OkoProtocol.java b/src/org/traccar/protocol/OkoProtocol.java deleted file mode 100644 index 9571ccc48..000000000 --- a/src/org/traccar/protocol/OkoProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.CharacterDelimiterFrameDecoder; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class OkoProtocol extends BaseProtocol { - - public OkoProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new OkoProtocolDecoder(OkoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OkoProtocolDecoder.java b/src/org/traccar/protocol/OkoProtocolDecoder.java deleted file mode 100644 index 5adf61494..000000000 --- a/src/org/traccar/protocol/OkoProtocolDecoder.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class OkoProtocolDecoder extends BaseProtocolDecoder { - - public OkoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("{") - .number("(d{15}),").optional() // imei - .number("(dd)(dd)(dd).d+,") // time - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(d+),") // satellites - .number("(d+.d+),") // adc - .number("(xx),") // event - .number("(d+.d+),") // power - .number("d,") // memory status - .number("(xx)") // io - .any() - .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; - if (parser.hasNext()) { - deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .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.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.KEY_EVENT, parser.next()); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_INPUT, parser.nextHexInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/OpenGtsProtocol.java b/src/org/traccar/protocol/OpenGtsProtocol.java deleted file mode 100644 index 5ef3260c6..000000000 --- a/src/org/traccar/protocol/OpenGtsProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.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; - -public class OpenGtsProtocol extends BaseProtocol { - - public OpenGtsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new OpenGtsProtocolDecoder(OpenGtsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java deleted file mode 100644 index b76cbfa85..000000000 --- a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 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.Protocol; -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.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -public class OpenGtsProtocolDecoder extends BaseHttpProtocolDecoder { - - private static final Pattern PATTERN = new PatternBuilder() - .text("$GPRMC,") - .number("(dd)(dd)(dd)(?:.d+)?,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+),") // speed - .number("(d+.d+)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .any() - .compile(); - - public OpenGtsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); - Map<String, List<String>> params = decoder.parameters(); - - Position position = new Position(getProtocolName()); - - for (Map.Entry<String, List<String>> entry : params.entrySet()) { - String value = entry.getValue().get(0); - switch (entry.getKey()) { - case "id": - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); - if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - break; - case "gprmc": - Parser parser = new Parser(PATTERN, value); - if (!parser.matches()) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - - DateBuilder dateBuilder = new DateBuilder() - .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()); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - break; - case "alt": - position.setAltitude(Double.parseDouble(value)); - break; - case "batt": - position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); - break; - default: - break; - } - } - - if (position.getDeviceId() != 0) { - sendResponse(channel, HttpResponseStatus.OK); - return position; - } else { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - } - -} diff --git a/src/org/traccar/protocol/OrionFrameDecoder.java b/src/org/traccar/protocol/OrionFrameDecoder.java deleted file mode 100644 index 948806609..000000000 --- a/src/org/traccar/protocol/OrionFrameDecoder.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - * 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 OrionFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - int length = 6; - - if (buf.readableBytes() >= length) { - - int type = buf.getUnsignedByte(buf.readerIndex() + 2) & 0x0f; - - if (type == OrionProtocolDecoder.MSG_USERLOG && buf.readableBytes() >= length + 5) { - - int index = buf.readerIndex() + 3; - int count = buf.getUnsignedByte(index) & 0x0f; - index += 5; - length += 5; - - for (int i = 0; i < count; i++) { - if (buf.readableBytes() < length) { - return null; - } - int logLength = buf.getUnsignedByte(index + 1); - index += logLength; - length += logLength; - } - - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - } else if (type == OrionProtocolDecoder.MSG_SYSLOG && buf.readableBytes() >= length + 12) { - - length += buf.getUnsignedShortLE(buf.readerIndex() + 8); - if (buf.readableBytes() >= length) { - return buf.readRetainedSlice(length); - } - - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/OrionProtocol.java b/src/org/traccar/protocol/OrionProtocol.java deleted file mode 100644 index 8485ae638..000000000 --- a/src/org/traccar/protocol/OrionProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class OrionProtocol extends BaseProtocol { - - public OrionProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new OrionFrameDecoder()); - pipeline.addLast(new OrionProtocolDecoder(OrionProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OrionProtocolDecoder.java b/src/org/traccar/protocol/OrionProtocolDecoder.java deleted file mode 100644 index af819989e..000000000 --- a/src/org/traccar/protocol/OrionProtocolDecoder.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.LinkedList; -import java.util.List; - -public class OrionProtocolDecoder extends BaseProtocolDecoder { - - public OrionProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_USERLOG = 0; - public static final int MSG_SYSLOG = 3; - - private static void sendResponse(Channel channel, ByteBuf buf) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(4); - response.writeByte('*'); - response.writeShort(buf.getUnsignedShort(buf.writerIndex() - 2)); - response.writeByte(buf.getUnsignedByte(buf.writerIndex() - 3)); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private static double convertCoordinate(int raw) { - int degrees = raw / 1000000; - double minutes = (raw % 1000000) / 10000.0; - return degrees + minutes / 60; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - int type = buf.readUnsignedByte() & 0x0f; - - if (type == MSG_USERLOG) { - - int header = buf.readUnsignedByte(); - - if ((header & 0x40) != 0) { - sendResponse(channel, buf); - } - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < (header & 0x0f); i++) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - buf.readUnsignedByte(); // length - position.set(Position.KEY_FLAGS, buf.readUnsignedShortLE()); - - 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()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - int satellites = buf.readUnsignedByte(); - position.setValid(satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - - positions.add(position); - } - - return positions; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/OsmAndProtocol.java b/src/org/traccar/protocol/OsmAndProtocol.java deleted file mode 100644 index d3aa2fd6f..000000000 --- a/src/org/traccar/protocol/OsmAndProtocol.java +++ /dev/null @@ -1,39 +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.protocol; - -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; - -public class OsmAndProtocol extends BaseProtocol { - - public OsmAndProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new OsmAndProtocolDecoder(OsmAndProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java deleted file mode 100644 index 3bc71de81..000000000 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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. - * 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 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.Protocol; -import org.traccar.helper.DateUtil; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.Map; - -public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { - - public OsmAndProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); - Map<String, List<String>> params = decoder.parameters(); - if (params.isEmpty()) { - decoder = new QueryStringDecoder(request.content().toString(StandardCharsets.US_ASCII), false); - params = decoder.parameters(); - } - - Position position = new Position(getProtocolName()); - position.setValid(true); - - Network network = new Network(); - - for (Map.Entry<String, List<String>> entry : params.entrySet()) { - for (String value : entry.getValue()) { - switch (entry.getKey()) { - case "id": - case "deviceid": - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); - if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - break; - case "valid": - position.setValid(Boolean.parseBoolean(value) || "1".equals(value)); - break; - case "timestamp": - try { - long timestamp = Long.parseLong(value); - if (timestamp < Integer.MAX_VALUE) { - timestamp *= 1000; - } - position.setTime(new Date(timestamp)); - } catch (NumberFormatException error) { - if (value.contains("T")) { - position.setTime(DateUtil.parseDate(value)); - } else { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - position.setTime(dateFormat.parse(value)); - } - } - break; - case "lat": - position.setLatitude(Double.parseDouble(value)); - break; - case "lon": - position.setLongitude(Double.parseDouble(value)); - break; - case "location": - String[] location = value.split(","); - position.setLatitude(Double.parseDouble(location[0])); - position.setLongitude(Double.parseDouble(location[1])); - break; - case "cell": - String[] cell = value.split(","); - if (cell.length > 4) { - network.addCellTower(CellTower.from( - Integer.parseInt(cell[0]), Integer.parseInt(cell[1]), - Integer.parseInt(cell[2]), Integer.parseInt(cell[3]), Integer.parseInt(cell[4]))); - } else { - network.addCellTower(CellTower.from( - Integer.parseInt(cell[0]), Integer.parseInt(cell[1]), - Integer.parseInt(cell[2]), Integer.parseInt(cell[3]))); - } - break; - case "wifi": - String[] wifi = value.split(","); - network.addWifiAccessPoint(WifiAccessPoint.from( - wifi[0].replace('-', ':'), Integer.parseInt(wifi[1]))); - break; - case "speed": - position.setSpeed(convertSpeed(Double.parseDouble(value), "kn")); - break; - case "bearing": - case "heading": - position.setCourse(Double.parseDouble(value)); - break; - case "altitude": - position.setAltitude(Double.parseDouble(value)); - break; - case "accuracy": - position.setAccuracy(Double.parseDouble(value)); - break; - case "hdop": - position.set(Position.KEY_HDOP, Double.parseDouble(value)); - break; - case "batt": - position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); - break; - case "driverUniqueId": - position.set(Position.KEY_DRIVER_UNIQUE_ID, value); - break; - default: - try { - position.set(entry.getKey(), Double.parseDouble(value)); - } catch (NumberFormatException e) { - switch (value) { - case "true": - position.set(entry.getKey(), true); - break; - case "false": - position.set(entry.getKey(), false); - break; - default: - position.set(entry.getKey(), value); - break; - } - } - break; - } - } - } - - if (position.getFixTime() == null) { - position.setTime(new Date()); - } - - if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { - position.setNetwork(network); - } - - if (position.getLatitude() == 0 && position.getLongitude() == 0) { - getLastLocation(position, position.getDeviceTime()); - } - - if (position.getDeviceId() != 0) { - sendResponse(channel, HttpResponseStatus.OK); - return position; - } else { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - } - -} diff --git a/src/org/traccar/protocol/OwnTracksProtocol.java b/src/org/traccar/protocol/OwnTracksProtocol.java deleted file mode 100644 index 0086371d8..000000000 --- a/src/org/traccar/protocol/OwnTracksProtocol.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 Jan-Piet Mens (jpmens@gmail.com) - * 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. - * 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.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; - -public class OwnTracksProtocol extends BaseProtocol { - - public OwnTracksProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new OwnTracksProtocolDecoder(OwnTracksProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java deleted file mode 100644 index 323d97fa3..000000000 --- a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2017 Jan-Piet Mens (jpmens@gmail.com) - * 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. - * 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 io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { - - public OwnTracksProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - JsonObject root = Json.createReader( - new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); - - if (!root.containsKey("_type")) { - sendResponse(channel, HttpResponseStatus.OK); - return null; - } - if (!root.getString("_type").equals("location") - && !root.getString("_type").equals("lwt")) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - - Position position = new Position(getProtocolName()); - String uniqueId; - - if (root.containsKey("topic")) { - uniqueId = root.getString("topic"); - if (root.containsKey("tid")) { - position.set("tid", root.getString("tid")); - } - } else { - uniqueId = root.getString("tid"); - } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); - if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - - if (root.getString("_type").equals("lwt")) { - sendResponse(channel, HttpResponseStatus.OK); - return null; - } - - if (root.containsKey("t") && root.getString("t").equals("p")) { - sendResponse(channel, HttpResponseStatus.OK); - return null; - } - - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(root.getJsonNumber("tst").longValue() * 1000)); - if (root.containsKey("sent")) { - position.setDeviceTime(new Date(root.getJsonNumber("sent").longValue() * 1000)); - } - - position.setValid(true); - - position.setLatitude(root.getJsonNumber("lat").doubleValue()); - position.setLongitude(root.getJsonNumber("lon").doubleValue()); - - if (root.containsKey("vel")) { - position.setSpeed(UnitsConverter.knotsFromKph(root.getInt("vel"))); - } - if (root.containsKey("alt")) { - position.setAltitude(root.getInt("alt")); - } - if (root.containsKey("cog")) { - position.setCourse(root.getInt("cog")); - } - if (root.containsKey("acc")) { - position.setAccuracy(root.getInt("acc")); - } - if (root.containsKey("t")) { - String trigger = root.getString("t"); - position.set("t", trigger); - Integer reportType = -1; - if (root.containsKey("rty")) { - reportType = root.getInt("rty"); - } - setEventOrAlarm(position, trigger, reportType); - } - if (root.containsKey("batt")) { - position.set(Position.KEY_BATTERY_LEVEL, root.getInt("batt")); - } - if (root.containsKey("uext")) { - position.set(Position.KEY_POWER, root.getJsonNumber("uext").doubleValue()); - } - if (root.containsKey("ubatt")) { - position.set(Position.KEY_BATTERY, root.getJsonNumber("ubatt").doubleValue()); - } - if (root.containsKey("vin")) { - position.set(Position.KEY_VIN, root.getString("vin")); - } - if (root.containsKey("name")) { - position.set(Position.KEY_VIN, root.getString("name")); - } - if (root.containsKey("rpm")) { - position.set(Position.KEY_RPM, root.getInt("rpm")); - } - if (root.containsKey("ign")) { - position.set(Position.KEY_IGNITION, root.getBoolean("ign")); - } - if (root.containsKey("motion")) { - position.set(Position.KEY_MOTION, root.getBoolean("motion")); - } - if (root.containsKey("odometer")) { - position.set(Position.KEY_ODOMETER, root.getJsonNumber("odometer").doubleValue() * 1000.0); - } - if (root.containsKey("hmc")) { - position.set(Position.KEY_HOURS, root.getJsonNumber("hmc").doubleValue() / 3600.0); - } - - if (root.containsKey("anum")) { - Integer numberOfAnalogueInputs = root.getInt("anum"); - for (Integer i = 0; i < numberOfAnalogueInputs; i++) { - String indexString = String.format("%02d", i); - if (root.containsKey("adda-" + indexString)) { - position.set(Position.PREFIX_ADC + (i + 1), root.getString("adda-" + indexString)); - } - if (root.containsKey("temp_c-" + indexString)) { - position.set(Position.PREFIX_TEMP + (i + 1), - root.getJsonNumber("temp_c-" + indexString).doubleValue()); - } - } - } - - sendResponse(channel, HttpResponseStatus.OK); - return position; - } - - private void setEventOrAlarm(Position position, String trigger, Integer reportType) { - switch (trigger) { - case "9": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "1": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "i": - position.set(Position.KEY_IGNITION, true); - break; - case "I": - position.set(Position.KEY_IGNITION, false); - break; - case "E": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "e": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "!": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "s": - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case "h": - switch (reportType) { - case 0: - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 1: - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - case 5: - default: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - } - break; - default: - break; - } - } -} diff --git a/src/org/traccar/protocol/PathAwayProtocol.java b/src/org/traccar/protocol/PathAwayProtocol.java deleted file mode 100644 index 6b5d75c5e..000000000 --- a/src/org/traccar/protocol/PathAwayProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class PathAwayProtocol extends BaseProtocol { - - public PathAwayProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new PathAwayProtocolDecoder(PathAwayProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/org/traccar/protocol/PathAwayProtocolDecoder.java deleted file mode 100644 index 02a15e34a..000000000 --- a/src/org/traccar/protocol/PathAwayProtocolDecoder.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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. - * 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 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class PathAwayProtocolDecoder extends BaseProtocolDecoder { - - public PathAwayProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$PWS,") - .number("d+,") // version - .expression("[^,]*,") // name - .expression("[^,]*,") // icon - .expression("[^,]*,") // color - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(-?d+.?d*),") // altitude - .number("(-?d+.?d*),") // speed - .number("(-?d+.?d*),") // course - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, decoder.parameters().get("UserName").get(0)); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, decoder.parameters().get("LOC").get(0)); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(true); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - if (channel != null) { - 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 deleted file mode 100644 index d88c1ab72..000000000 --- a/src/org/traccar/protocol/PiligrimProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class PiligrimProtocol extends BaseProtocol { - - public PiligrimProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(16384)); - pipeline.addLast(new PiligrimProtocolDecoder(PiligrimProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/org/traccar/protocol/PiligrimProtocolDecoder.java deleted file mode 100644 index 47aa86da7..000000000 --- a/src/org/traccar/protocol/PiligrimProtocolDecoder.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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. - * 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 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; - -public class PiligrimProtocolDecoder extends BaseProtocolDecoder { - - public PiligrimProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void sendResponse(Channel channel, String message) { - if (channel != null) { - FullHttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK, - Unpooled.copiedBuffer(message, StandardCharsets.US_ASCII)); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - public static final int MSG_GPS = 0xF1; - public static final int MSG_GPS_SENSORS = 0xF2; - public static final int MSG_EVENTS = 0xF3; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - String uri = request.uri(); - - if (uri.startsWith("/config")) { - - sendResponse(channel, "CONFIG: OK"); - - } else if (uri.startsWith("/addlog")) { - - sendResponse(channel, "ADDLOG: OK"); - - } else if (uri.startsWith("/inform")) { - - sendResponse(channel, "INFORM: OK"); - - } else if (uri.startsWith("/bingps")) { - - sendResponse(channel, "BINGPS: OK"); - - QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, decoder.parameters().get("imei").get(0)); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - ByteBuf buf = request.content(); - - while (buf.readableBytes() > 2) { - - buf.readUnsignedByte(); // header - int type = buf.readUnsignedByte(); - buf.readUnsignedByte(); // length - - if (type == MSG_GPS || type == MSG_GPS_SENSORS) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDay(buf.readUnsignedByte()) - .setMonth(buf.getByte(buf.readerIndex()) & 0x0f) - .setYear(2010 + (buf.readUnsignedByte() >> 4)) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); - - double latitude = buf.readUnsignedByte(); - latitude += buf.readUnsignedByte() / 60.0; - latitude += buf.readUnsignedByte() / 6000.0; - latitude += buf.readUnsignedByte() / 600000.0; - - double longitude = buf.readUnsignedByte(); - longitude += buf.readUnsignedByte() / 60.0; - longitude += buf.readUnsignedByte() / 6000.0; - longitude += buf.readUnsignedByte() / 600000.0; - - int flags = buf.readUnsignedByte(); - if (BitUtil.check(flags, 0)) { - latitude = -latitude; - } - if (BitUtil.check(flags, 1)) { - longitude = -longitude; - } - position.setLatitude(latitude); - position.setLongitude(longitude); - - int satellites = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, satellites); - position.setValid(satellites >= 3); - - position.setSpeed(buf.readUnsignedByte()); - - double course = buf.readUnsignedByte() << 1; - course += (flags >> 2) & 1; - course += buf.readUnsignedByte() / 100.0; - position.setCourse(course); - - if (type == MSG_GPS_SENSORS) { - double power = buf.readUnsignedByte(); - power += buf.readUnsignedByte() << 8; - position.set(Position.KEY_POWER, power * 0.01); - - double battery = buf.readUnsignedByte(); - battery += buf.readUnsignedByte() << 8; - position.set(Position.KEY_BATTERY, battery * 0.01); - - buf.skipBytes(6); - } - - positions.add(position); - - } else if (type == MSG_EVENTS) { - - buf.skipBytes(13); - } - } - - return positions; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/PretraceProtocol.java b/src/org/traccar/protocol/PretraceProtocol.java deleted file mode 100644 index f753cbdb4..000000000 --- a/src/org/traccar/protocol/PretraceProtocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class PretraceProtocol extends BaseProtocol { - - public PretraceProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new PretraceProtocolEncoder()); - pipeline.addLast(new PretraceProtocolDecoder(PretraceProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/PretraceProtocolDecoder.java b/src/org/traccar/protocol/PretraceProtocolDecoder.java deleted file mode 100644 index a19384e62..000000000 --- a/src/org/traccar/protocol/PretraceProtocolDecoder.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 PretraceProtocolDecoder extends BaseProtocolDecoder { - - public PretraceProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .number("(d{15})") // imei - .number("Uddd") // type - .number("d") // gps type - .expression("([AV])") // validity - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(dd)(dd.dddd)") // latitude - .expression("([NS])") - .number("(ddd)(dd.dddd)") // longitude - .expression("([EW])") - .number("(ddd)") // speed - .number("(ddd)") // course - .number("(xxx)") // altitude - .number("(x{8})") // odometer - .number("(x)") // satellites - .number("(dd)") // hdop - .number("(dd)") // gsm - .expression("(.{8}),&") // state - .expression("(.+)?") // optional data - .text("^") - .number("xx") // checksum - .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(parser.next().equals("A")); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - position.setAltitude(parser.nextHexInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextHexInt(0)); - position.set(Position.KEY_SATELLITES, parser.nextHexInt(0)); - position.set(Position.KEY_HDOP, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - - parser.next(); // state - - if (parser.hasNext()) { - for (String value : parser.next().split(",")) { - switch (value.charAt(0)) { - case 'P': - if (value.charAt(1) == '1') { - if (value.charAt(4) == '%') { - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value.substring(2, 4))); - } else { - position.set(Position.KEY_BATTERY, Integer.parseInt(value.substring(2), 16) * 0.01); - } - } else { - position.set(Position.KEY_POWER, Integer.parseInt(value.substring(2), 16) * 0.01); - } - break; - case 'T': - double temperature = Integer.parseInt(value.substring(2), 16) * 0.25; - if (value.charAt(1) == '1') { - position.set(Position.KEY_DEVICE_TEMP, temperature); - } else { - position.set(Position.PREFIX_TEMP + (value.charAt(1) - '0'), temperature); - } - break; - case 'F': - position.set("fuel" + (value.charAt(1) - '0'), Integer.parseInt(value.substring(2), 16) * 0.01); - break; - case 'R': - position.set(Position.KEY_DRIVER_UNIQUE_ID, value.substring(3)); - break; - default: - break; - } - } - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/PretraceProtocolEncoder.java b/src/org/traccar/protocol/PretraceProtocolEncoder.java deleted file mode 100644 index 9cf951e3b..000000000 --- a/src/org/traccar/protocol/PretraceProtocolEncoder.java +++ /dev/null @@ -1,46 +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.protocol; - -import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; -import org.traccar.helper.Checksum; -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: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/PricolProtocol.java b/src/org/traccar/protocol/PricolProtocol.java deleted file mode 100644 index 6821cd949..000000000 --- a/src/org/traccar/protocol/PricolProtocol.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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.FixedLengthFrameDecoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class PricolProtocol extends BaseProtocol { - - public PricolProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new FixedLengthFrameDecoder(64)); - pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/PricolProtocolDecoder.java b/src/org/traccar/protocol/PricolProtocolDecoder.java deleted file mode 100644 index 190c68258..000000000 --- a/src/org/traccar/protocol/PricolProtocolDecoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; - -public class PricolProtocolDecoder extends BaseProtocolDecoder { - - public PricolProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // header - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, buf.readSlice(7).toString(StandardCharsets.US_ASCII)); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set("eventType", buf.readUnsignedByte()); - position.set("packetVersion", buf.readUnsignedByte()); - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_GPS, buf.readUnsignedByte()); - - position.setTime(new DateBuilder() - .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); - - position.setValid(true); - - double lat = buf.getUnsignedShort(buf.readerIndex()) / 100; - lat += (buf.readUnsignedShort() % 100 * 10000 + buf.readUnsignedShort()) / 600000.0; - position.setLatitude(buf.readUnsignedByte() == 'S' ? -lat : lat); - - double lon = buf.getUnsignedMedium(buf.readerIndex()) / 100; - lon += (buf.readUnsignedMedium() % 100 * 10000 + buf.readUnsignedShort()) / 600000.0; - position.setLongitude(buf.readUnsignedByte() == 'W' ? -lon : lon); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - position.set(Position.KEY_INPUT, buf.readUnsignedShort()); - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - - position.set("analogAlerts", buf.readUnsignedByte()); - position.set("customAlertTypes", buf.readUnsignedShort()); - - for (int i = 1; i <= 5; i++) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort()); - } - - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - - if (channel != null) { - 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 deleted file mode 100644 index aac84205d..000000000 --- a/src/org/traccar/protocol/ProgressProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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; -public class ProgressProtocol extends BaseProtocol { - - public ProgressProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); - pipeline.addLast(new ProgressProtocolDecoder(ProgressProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ProgressProtocolDecoder.java b/src/org/traccar/protocol/ProgressProtocolDecoder.java deleted file mode 100644 index 0025cd9e7..000000000 --- a/src/org/traccar/protocol/ProgressProtocolDecoder.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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.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.Protocol; -import org.traccar.helper.BitUtil; -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; - -public class ProgressProtocolDecoder extends BaseProtocolDecoder { - - private long lastIndex; - private long newIndex; - - public ProgressProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_NULL = 0; - public static final int MSG_IDENT = 1; - public static final int MSG_IDENT_FULL = 2; - public static final int MSG_POINT = 10; - public static final int MSG_LOG_SYNC = 100; - public static final int MSG_LOGMSG = 101; - public static final int MSG_TEXT = 102; - public static final int MSG_ALARM = 200; - public static final int MSG_ALARM_RECIEVED = 201; - - private void requestArchive(Channel channel) { - if (lastIndex == 0) { - lastIndex = newIndex; - } else if (newIndex > lastIndex) { - 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())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - int type = buf.readUnsignedShortLE(); - buf.readUnsignedShortLE(); // length - - if (type == MSG_IDENT || type == MSG_IDENT_FULL) { - - buf.readUnsignedIntLE(); // id - int length = buf.readUnsignedShortLE(); - buf.skipBytes(length); - length = buf.readUnsignedShortLE(); - buf.skipBytes(length); - 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) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - int recordCount = 1; - if (type == MSG_LOGMSG) { - recordCount = buf.readUnsignedShortLE(); - } - - for (int j = 0; j < recordCount; j++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (type == MSG_LOGMSG) { - position.set(Position.KEY_ARCHIVE, true); - int subtype = buf.readUnsignedShortLE(); - if (subtype == MSG_ALARM) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - if (buf.readUnsignedShortLE() > buf.readableBytes()) { - lastIndex += 1; - break; // workaround for device bug - } - lastIndex = buf.readUnsignedIntLE(); - position.set(Position.KEY_INDEX, lastIndex); - } else { - newIndex = buf.readUnsignedIntLE(); - } - - 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.readUnsignedIntLE()); - - long extraFlags = buf.readLongLE(); - - if (BitUtil.check(extraFlags, 0)) { - int count = buf.readUnsignedShortLE(); - for (int i = 1; i <= count; i++) { - position.set(Position.PREFIX_ADC + i, buf.readUnsignedShortLE()); - } - } - - if (BitUtil.check(extraFlags, 1)) { - 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", 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.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); - } - - buf.readUnsignedIntLE(); // crc - - positions.add(position); - } - - requestArchive(channel); - - return positions; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Pt3000Protocol.java b/src/org/traccar/protocol/Pt3000Protocol.java deleted file mode 100644 index 1ad0026a3..000000000 --- a/src/org/traccar/protocol/Pt3000Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Pt3000Protocol extends BaseProtocol { - - public Pt3000Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Pt3000ProtocolDecoder(Pt3000Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/org/traccar/protocol/Pt3000ProtocolDecoder.java deleted file mode 100644 index e7f9e062a..000000000 --- a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class Pt3000ProtocolDecoder extends BaseProtocolDecoder { - - public Pt3000ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("%(d+),") // imei - .text("$GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Pt502FrameDecoder.java b/src/org/traccar/protocol/Pt502FrameDecoder.java deleted file mode 100644 index 316cd987f..000000000 --- a/src/org/traccar/protocol/Pt502FrameDecoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - * 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; - -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, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf - && buf.toString(buf.readerIndex() + BINARY_HEADER, 4, StandardCharsets.US_ASCII).equals("$PHD")) { - - 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 (buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.skipBytes(BINARY_HEADER); - } - - 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 deleted file mode 100644 index 5afb9451d..000000000 --- a/src/org/traccar/protocol/Pt502Protocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class Pt502Protocol extends BaseProtocol { - - public Pt502Protocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_SET_TIMEZONE, - Command.TYPE_ALARM_SPEED, - Command.TYPE_OUTPUT_CONTROL, - Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Pt502FrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Pt502ProtocolEncoder()); - pipeline.addLast(new Pt502ProtocolDecoder(Pt502Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java deleted file mode 100644 index 12210652b..000000000 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ /dev/null @@ -1,212 +0,0 @@ -/*
- * 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");
- * 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.Context;
-import org.traccar.DeviceSession;
-import org.traccar.NetworkMessage;
-import org.traccar.Protocol;
-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 ByteBuf photo;
-
- public Pt502ProtocolDecoder(Protocol protocol) {
- super(protocol);
- }
-
- private static final Pattern PATTERN = new PatternBuilder()
- .any().text("$")
- .expression("([^,]+),") // type
- .number("(d+),") // id
- .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss)
- .expression("([AV]),") // validity
- .number("(d+)(dd.dddd),") // latitude
- .expression("([NS]),")
- .number("(d+)(dd.dddd),") // longitude
- .expression("([EW]),")
- .number("(d+.d+)?,") // speed
- .number("(d+.d+)?,") // course
- .number("(dd)(dd)(dd),,,") // date (ddmmyy)
- .expression("./")
- .expression("([01])+,") // input
- .expression("([01])+/") // output
- .expression("([^/]+)?/") // adc
- .number("(d+)") // odometer
- .expression("/([^/]+)?/") // rfid
- .number("(xxx)").optional(2) // state
- .any()
- .compile();
-
- private String decodeAlarm(String value) {
- switch (value) {
- case "IN1":
- return Position.ALARM_SOS;
- case "GOF":
- return Position.ALARM_GEOFENCE;
- case "TOW":
- return Position.ALARM_TOW;
- case "HDA":
- return Position.ALARM_ACCELERATION;
- case "HDB":
- return Position.ALARM_BRAKING;
- case "FDA":
- return Position.ALARM_FATIGUE_DRIVING;
- case "SKA":
- return Position.ALARM_VIBRATION;
- case "PMA":
- return Position.ALARM_MOVEMENT;
- case "CPA":
- return Position.ALARM_POWER_CUT;
- default:
- return null;
- }
- }
-
- private Position decodePosition(Channel channel, SocketAddress remoteAddress, String sentence) {
-
- Parser parser = new Parser(PATTERN, sentence);
- if (!parser.matches()) {
- return null;
- }
-
- Position position = new Position(getProtocolName());
- position.set(Position.KEY_ALARM, decodeAlarm(parser.next()));
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- DateBuilder dateBuilder = new DateBuilder()
- .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
-
- position.setValid(parser.next().equals("A"));
- position.setLatitude(parser.nextCoordinate());
- position.setLongitude(parser.nextCoordinate());
- position.setSpeed(parser.nextDouble(0));
- position.setCourse(parser.nextDouble(0));
-
- dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
- position.setTime(dateBuilder.getDate());
-
- position.set(Position.KEY_INPUT, parser.next());
- position.set(Position.KEY_OUTPUT, parser.next());
-
- if (parser.hasNext()) {
- String[] values = parser.next().split(",");
- for (int i = 0; i < values.length; i++) {
- position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(values[i], 16));
- }
- }
-
- position.set(Position.KEY_ODOMETER, parser.nextInt(0));
- position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
-
- if (parser.hasNext()) {
- int value = parser.nextHexInt(0);
- position.set(Position.KEY_BATTERY, value >> 8);
- position.set(Position.KEY_RSSI, (value >> 4) & 0xf);
- position.set(Position.KEY_SATELLITES, value & 0xf);
- }
-
- 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/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java deleted file mode 100644 index ed18208cc..000000000 --- a/src/org/traccar/protocol/Pt502ProtocolEncoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 java.util.TimeZone; - -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class Pt502ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { - - @Override - public String formatValue(String key, Object value) { - if (key.equals(Command.KEY_TIMEZONE)) { - return String.valueOf(TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); - } - - return null; - } - - @Override - protected String formatCommand(Command command, String format, String... keys) { - return formatCommand(command, format, this, keys); - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "{%s}\r\n", Command.KEY_DATA); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "#OPC{%s},{%s}\r\n", Command.KEY_INDEX, Command.KEY_DATA); - case Command.TYPE_SET_TIMEZONE: - return formatCommand(command, "#TMZ{%s}\r\n", Command.KEY_TIMEZONE); - case Command.TYPE_ALARM_SPEED: - return formatCommand(command, "#SPD{%s}\r\n", Command.KEY_DATA); - case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "#PHO\r\n"); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Pt60Protocol.java b/src/org/traccar/protocol/Pt60Protocol.java deleted file mode 100644 index c502426c5..000000000 --- a/src/org/traccar/protocol/Pt60Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class Pt60Protocol extends BaseProtocol { - - public Pt60Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Pt60ProtocolDecoder(Pt60Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/org/traccar/protocol/Pt60ProtocolDecoder.java deleted file mode 100644 index 6a3fe2734..000000000 --- a/src/org/traccar/protocol/Pt60ProtocolDecoder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.regex.Pattern; - -public class Pt60ProtocolDecoder extends BaseProtocolDecoder { - - public Pt60ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_G_TRACK = 6; - public static final int MSG_G_STEP_COUNT = 13; - public static final int MSG_G_HEART_RATE = 14; - - public static final int MSG_B_POSITION = 1; - - private static final Pattern PATTERN = new PatternBuilder() - .expression("@(.)#@[,|]") // header - .number("V?dd[,|]") // protocol version - .number("(d+)[,|]") // type - .number("(d+)[,|]") // imei - .number("d+[,|]") // imsi - .groupBegin() - .expression("[^,|]+[,|]").optional() // firmware version - .number("[01][,|]") // state - .number("d+[,|]") // battery - .groupEnd("?") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)[,|]") // time (hhmmss) - .expression("(.*)") // data - .expression("[,|]") - .compile(); - - private void sendResponse(Channel channel, SocketAddress remoteAddress, String format, int type, String imei) { - if (channel != null) { - String message; - String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); - if (format.equals("G")) { - message = String.format("@G#@,V01,38,%s,@R#@", time); - } else { - message = String.format("@B#@|01|%03d|%s|0|%s|@E#@", type + 1, imei, time); - } - channel.writeAndFlush(new NetworkMessage(message, remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - String format = parser.next(); - int type = parser.nextInt(); - String imei = parser.next(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - sendResponse(channel, remoteAddress, format, type, imei); - - if (format.equals("G")) { - - if (type != MSG_G_TRACK && type != MSG_G_STEP_COUNT && type != MSG_G_HEART_RATE) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setDeviceTime(parser.nextDateTime()); - - String[] values = parser.next().split(","); - - if (type == MSG_G_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_G_STEP_COUNT: - position.set(Position.KEY_STEPS, Integer.parseInt(values[0])); - break; - case MSG_G_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; - - } else { - - if (type != MSG_B_POSITION) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setDeviceTime(parser.nextDateTime()); - - String[] values = parser.next().split("\\|"); - - if (Integer.parseInt(values[values.length - 1]) == 2) { - - getLastLocation(position, position.getDeviceTime()); - - Network network = new Network(); - - for (int i = 0; i < values.length - 1; i++) { - String[] cellValues = values[i].split(","); - CellTower tower = new CellTower(); - tower.setCellId(Long.parseLong(cellValues[0])); - tower.setLocationAreaCode(Integer.parseInt(cellValues[1])); - tower.setMobileNetworkCode(Integer.parseInt(cellValues[2])); - tower.setMobileCountryCode(Integer.parseInt(cellValues[3])); - tower.setSignalStrength(Integer.parseInt(cellValues[4])); - network.addCellTower(tower); - } - - position.setNetwork(network); - - - } else { - - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - - position.setLatitude(Double.parseDouble(values[0])); - position.setLongitude(Double.parseDouble(values[1])); - - } - - return position; - - } - } - -} diff --git a/src/org/traccar/protocol/RaveonProtocol.java b/src/org/traccar/protocol/RaveonProtocol.java deleted file mode 100644 index 44faadb3b..000000000 --- a/src/org/traccar/protocol/RaveonProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class RaveonProtocol extends BaseProtocol { - - public RaveonProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new RaveonProtocolDecoder(RaveonProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RaveonProtocolDecoder.java b/src/org/traccar/protocol/RaveonProtocolDecoder.java deleted file mode 100644 index 50acd20a1..000000000 --- a/src/org/traccar/protocol/RaveonProtocolDecoder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 RaveonProtocolDecoder extends BaseProtocolDecoder { - - public RaveonProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$PRAVE,") - .number("(d+),") // id - .number("d+,") - .number("(-?)(d+)(dd.d+),") // latitude - .number("(-?)(d+)(dd.d+),") // longitude - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d),") // validity - .number("(d+),") // satellites - .number("(-?d+),") // altitude - .number("(-?d+),") // temperature - .number("(d+.d+),") // power - .number("(d+),") // inputs - .number("(-?d+),") // gsm - .number("(d+),") // speed - .number("(d+),") // course - .expression("([PMACIVSX])?,") // status - .any() - .compile(); - - @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()); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); - - position.setValid(parser.nextInt(0) != 0); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - - position.setAltitude(parser.nextInt(0)); - - position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); - position.set(Position.KEY_POWER, parser.nextDouble(0)); - position.set(Position.KEY_INPUT, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - - position.set(Position.KEY_ALARM, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/RecodaProtocol.java b/src/org/traccar/protocol/RecodaProtocol.java deleted file mode 100644 index 0bc9870bc..000000000 --- a/src/org/traccar/protocol/RecodaProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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; -public class RecodaProtocol extends BaseProtocol { - - public RecodaProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); - pipeline.addLast(new RecodaProtocolDecoder(RecodaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RecodaProtocolDecoder.java b/src/org/traccar/protocol/RecodaProtocolDecoder.java deleted file mode 100644 index 04098225f..000000000 --- a/src/org/traccar/protocol/RecodaProtocolDecoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class RecodaProtocolDecoder extends BaseProtocolDecoder { - - public RecodaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_HEARTBEAT = 0x00001001; - public static final int MSG_REQUEST_RESPONSE = 0x20000001; - public static final int MSG_SIGNAL_LINK_REGISTRATION = 0x20001001; - public static final int MSG_EVENT_NOTICE = 0x20002001; - public static final int MSG_GPS_DATA = 0x20001011; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int type = buf.readIntLE(); - buf.readUnsignedIntLE(); // length - - if (type != MSG_HEARTBEAT) { - buf.readUnsignedShortLE(); // version - buf.readUnsignedShortLE(); // index - } - - if (type == MSG_SIGNAL_LINK_REGISTRATION) { - - getDeviceSession(channel, remoteAddress, buf.readSlice(12).toString(StandardCharsets.US_ASCII)); - - } else if (type == MSG_GPS_DATA) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readLongLE())); - - int flags = buf.readUnsignedByte(); - - if (BitUtil.check(flags, 0)) { - - buf.readUnsignedShortLE(); // declination - - 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.readUnsignedIntLE() / 3600.0); - position.setLatitude(position.getLatitude() + buf.readUnsignedIntLE() / 3600.0); - - int status = buf.readUnsignedByte(); - - position.setValid(BitUtil.check(status, 0)); - if (BitUtil.check(status, 1)) { - position.setLongitude(-position.getLongitude()); - } - if (!BitUtil.check(status, 2)) { - position.setLatitude(-position.getLatitude()); - } - - } else { - - getLastLocation(position, position.getDeviceTime()); - - } - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/RetranslatorFrameDecoder.java b/src/org/traccar/protocol/RetranslatorFrameDecoder.java deleted file mode 100644 index 4edd09418..000000000 --- a/src/org/traccar/protocol/RetranslatorFrameDecoder.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.readRetainedSlice(length); - } else { - return null; - } - } - -} diff --git a/src/org/traccar/protocol/RetranslatorProtocol.java b/src/org/traccar/protocol/RetranslatorProtocol.java deleted file mode 100644 index fae81f7d2..000000000 --- a/src/org/traccar/protocol/RetranslatorProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - -public class RetranslatorProtocol extends BaseProtocol { - - public RetranslatorProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new RetranslatorFrameDecoder()); - pipeline.addLast(new RetranslatorProtocolDecoder(RetranslatorProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/org/traccar/protocol/RetranslatorProtocolDecoder.java deleted file mode 100644 index 0688c9b0e..000000000 --- a/src/org/traccar/protocol/RetranslatorProtocolDecoder.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index de1026672..000000000 --- a/src/org/traccar/protocol/RitiProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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; -public class RitiProtocol extends BaseProtocol { - - public RitiProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); - pipeline.addLast(new RitiProtocolDecoder(RitiProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RitiProtocolDecoder.java b/src/org/traccar/protocol/RitiProtocolDecoder.java deleted file mode 100644 index 46267ca90..000000000 --- a/src/org/traccar/protocol/RitiProtocolDecoder.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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 RitiProtocolDecoder extends BaseProtocolDecoder { - - public RitiProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedShort())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set("mode", buf.readUnsignedByte()); - position.set(Position.KEY_COMMAND, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - - buf.skipBytes(5); // status - buf.readUnsignedShortLE(); // idleCount - buf.readUnsignedShortLE(); // idleTime in seconds - - 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) '*'); - String gprmc = buf.toString(buf.readerIndex(), end - buf.readerIndex(), StandardCharsets.US_ASCII); - Parser parser = new Parser(PATTERN, gprmc); - if (!parser.matches()) { - return null; - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/RoboTrackFrameDecoder.java b/src/org/traccar/protocol/RoboTrackFrameDecoder.java deleted file mode 100644 index 85ed6c76f..000000000 --- a/src/org/traccar/protocol/RoboTrackFrameDecoder.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 (buf.getUnsignedByte(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 deleted file mode 100644 index c2c531293..000000000 --- a/src/org/traccar/protocol/RoboTrackProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - -public class RoboTrackProtocol extends BaseProtocol { - - public RoboTrackProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new RoboTrackFrameDecoder()); - pipeline.addLast(new RoboTrackProtocolDecoder(RoboTrackProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/org/traccar/protocol/RoboTrackProtocolDecoder.java deleted file mode 100644 index b613f31d7..000000000 --- a/src/org/traccar/protocol/RoboTrackProtocolDecoder.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index 1ac62570a..000000000 --- a/src/org/traccar/protocol/RuptelaProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class RuptelaProtocol extends BaseProtocol { - - public RuptelaProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_CONFIGURATION, - Command.TYPE_GET_VERSION, - Command.TYPE_FIRMWARE_UPDATE, - Command.TYPE_OUTPUT_CONTROL, - Command.TYPE_SET_CONNECTION, - Command.TYPE_SET_ODOMETER); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); - pipeline.addLast(new RuptelaProtocolEncoder()); - pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java deleted file mode 100644 index b043b6201..000000000 --- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DataConverter; -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; - -public class RuptelaProtocolDecoder extends BaseProtocolDecoder { - - public RuptelaProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_RECORDS = 1; - public static final int MSG_DEVICE_CONFIGURATION = 2; - public static final int MSG_DEVICE_VERSION = 3; - public static final int MSG_FIRMWARE_UPDATE = 4; - public static final int MSG_SET_CONNECTION = 5; - public static final int MSG_SET_ODOMETER = 6; - public static final int MSG_SMS_VIA_GPRS_RESPONSE = 7; - public static final int MSG_SMS_VIA_GPRS = 8; - public static final int MSG_DTCS = 9; - public static final int MSG_SET_IO = 17; - public static final int MSG_EXTENDED_RECORDS = 68; - - private Position decodeCommandResponse(DeviceSession deviceSession, int type, ByteBuf buf) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_TYPE, type); - - switch (type) { - case MSG_DEVICE_CONFIGURATION: - case MSG_DEVICE_VERSION: - case MSG_FIRMWARE_UPDATE: - case MSG_SMS_VIA_GPRS_RESPONSE: - position.set(Position.KEY_RESULT, - buf.toString(buf.readerIndex(), buf.readableBytes() - 2, StandardCharsets.US_ASCII).trim()); - return position; - case MSG_SET_IO: - position.set(Position.KEY_RESULT, - String.valueOf(buf.readUnsignedByte())); - return position; - default: - return null; - } - } - - private long readValue(ByteBuf buf, int length, boolean signed) { - switch (length) { - case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); - case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); - case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); - default: - return buf.readLong(); - } - } - - private void decodeParameter(Position position, int id, ByteBuf buf, int length) { - switch (id) { - case 2: - case 3: - case 4: - position.set("di" + (id - 1), readValue(buf, length, false)); - break; - case 5: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); - break; - case 74: - position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); - break; - case 78: - case 79: - case 80: - position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedShort(); // data length - - String imei = String.format("%015d", buf.readLong()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - int type = buf.readUnsignedByte(); - - if (type == MSG_RECORDS || type == MSG_EXTENDED_RECORDS) { - - List<Position> positions = new LinkedList<>(); - - buf.readUnsignedByte(); // records left - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - buf.readUnsignedByte(); // timestamp extension - - if (type == MSG_EXTENDED_RECORDS) { - buf.readUnsignedByte(); // record extension - } - - buf.readUnsignedByte(); // priority (reserved) - - position.setValid(true); - position.setLongitude(buf.readInt() / 10000000.0); - position.setLatitude(buf.readInt() / 10000000.0); - position.setAltitude(buf.readUnsignedShort() / 10.0); - position.setCourse(buf.readUnsignedShort() / 100.0); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - - position.set(Position.KEY_HDOP, buf.readUnsignedByte() / 10.0); - - if (type == MSG_EXTENDED_RECORDS) { - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - } else { - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - } - - // Read 1 byte data - int cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 1); - } - - // Read 2 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 2); - } - - // Read 4 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 4); - } - - // Read 8 byte data - cnt = buf.readUnsignedByte(); - for (int j = 0; j < cnt; j++) { - int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 8); - } - - positions.add(position); - } - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Unpooled.wrappedBuffer(DataConverter.parseHex("0002640113bc")), remoteAddress)); - } - - return positions; - - } else if (type == MSG_DTCS) { - - List<Position> positions = new LinkedList<>(); - - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // reserved - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - position.setValid(true); - position.setLongitude(buf.readInt() / 10000000.0); - position.setLatitude(buf.readInt() / 10000000.0); - - if (buf.readUnsignedByte() == 2) { - position.set(Position.KEY_ARCHIVE, true); - } - - position.set(Position.KEY_DTCS, buf.readSlice(5).toString(StandardCharsets.US_ASCII)); - - positions.add(position); - } - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Unpooled.wrappedBuffer(DataConverter.parseHex("00026d01c4a4")), remoteAddress)); - } - - return positions; - - } else { - - return decodeCommandResponse(deviceSession, type, buf); - - } - } - -} diff --git a/src/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/org/traccar/protocol/RuptelaProtocolEncoder.java deleted file mode 100644 index 4242584c9..000000000 --- a/src/org/traccar/protocol/RuptelaProtocolEncoder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.Checksum; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class RuptelaProtocolEncoder extends BaseProtocolEncoder { - - private ByteBuf encodeContent(int type, ByteBuf content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeShort(1 + content.readableBytes()); - buf.writeByte(100 + type); - buf.writeBytes(content); - buf.writeShort(Checksum.crc16(Checksum.CRC16_KERMIT, buf.nioBuffer(2, buf.writerIndex() - 2))); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - ByteBuf content = Unpooled.buffer(); - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - content.writeBytes(command.getString(Command.KEY_DATA).getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); - case Command.TYPE_CONFIGURATION: - content.writeBytes((command.getString(Command.KEY_DATA) + "\r\n").getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_CONFIGURATION, content); - case Command.TYPE_GET_VERSION: - return encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_VERSION, content); - case Command.TYPE_FIRMWARE_UPDATE: - content.writeBytes("|FU_STRT*\r\n".getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); - case Command.TYPE_OUTPUT_CONTROL: - content.writeInt(command.getInteger(Command.KEY_INDEX)); - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); - case Command.TYPE_SET_CONNECTION: - String c = command.getString(Command.KEY_SERVER) + "," + command.getInteger(Command.KEY_PORT) + ",TCP"; - content.writeBytes(c.getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); - case Command.TYPE_SET_ODOMETER: - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/SabertekFrameDecoder.java b/src/org/traccar/protocol/SabertekFrameDecoder.java deleted file mode 100644 index ad5000bf8..000000000 --- a/src/org/traccar/protocol/SabertekFrameDecoder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 (endIndex >= 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 deleted file mode 100644 index 0ec847b60..000000000 --- a/src/org/traccar/protocol/SabertekProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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; - -public class SabertekProtocol extends BaseProtocol { - - public SabertekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new SabertekFrameDecoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SabertekProtocolDecoder(SabertekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SabertekProtocolDecoder.java b/src/org/traccar/protocol/SabertekProtocolDecoder.java deleted file mode 100644 index 3033aa2cc..000000000 --- a/src/org/traccar/protocol/SabertekProtocolDecoder.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index 6799c57e6..000000000 --- a/src/org/traccar/protocol/SanavProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class SanavProtocol extends BaseProtocol { - - public SanavProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SanavProtocolDecoder.java b/src/org/traccar/protocol/SanavProtocolDecoder.java deleted file mode 100644 index 7e1c158e6..000000000 --- a/src/org/traccar/protocol/SanavProtocolDecoder.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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.util.regex.Pattern; - -public class SanavProtocolDecoder extends BaseProtocolDecoder { - - public SanavProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("imei[:=]") - .number("(d+)") // imei - .expression("&?rmc[:=]") - .text("$GPRMC,") - .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .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(); - - @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()); - - DateBuilder dateBuilder = new DateBuilder() - .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()); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - if (parser.hasNext()) { - int io = parser.nextHexInt(); - 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/SatsolProtocol.java b/src/org/traccar/protocol/SatsolProtocol.java deleted file mode 100644 index b69fdd1fe..000000000 --- a/src/org/traccar/protocol/SatsolProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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; - -public class SatsolProtocol extends BaseProtocol { - - public SatsolProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); - pipeline.addLast(new SatsolProtocolDecoder(SatsolProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SatsolProtocolDecoder.java b/src/org/traccar/protocol/SatsolProtocolDecoder.java deleted file mode 100644 index c457d5620..000000000 --- a/src/org/traccar/protocol/SatsolProtocolDecoder.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Anton Tananaev (anton@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.Protocol; -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.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class SatsolProtocolDecoder extends BaseProtocolDecoder { - - public SatsolProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedShortLE(); // checksum - buf.readUnsignedShortLE(); // preamble - long id = buf.readUnsignedIntLE(); - buf.readUnsignedShortLE(); // length - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.isReadable()) { - - buf.readUnsignedShortLE(); // checksum - buf.readUnsignedShortLE(); // checksum - buf.readUnsignedShortLE(); // type - int length = buf.readUnsignedShortLE(); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - position.setLatitude(buf.readUnsignedIntLE() * 0.000001); - position.setLongitude(buf.readUnsignedIntLE() * 0.000001); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.01)); - position.setAltitude(buf.readShortLE()); - position.setCourse(buf.readUnsignedShortLE()); - position.setValid(buf.readUnsignedByte() > 0); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - if (BitUtil.check(buf.readUnsignedByte(), 0)) { - position.set(Position.KEY_ARCHIVE, true); - } - - positions.add(position); - - buf.skipBytes(length); - - } - - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShortLE(0); - response.writeShortLE(0x4CBF); // preamble - response.writeIntLE((int) id); - response.writeShortLE(0); - response.setShortLE(0, Checksum.crc16( - Checksum.CRC16_CCITT_FALSE, response.nioBuffer(2, response.readableBytes() - 2))); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/SigfoxProtocol.java b/src/org/traccar/protocol/SigfoxProtocol.java deleted file mode 100644 index e2f2cbe1f..000000000 --- a/src/org/traccar/protocol/SigfoxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class SigfoxProtocol extends BaseProtocol { - - public SigfoxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); - pipeline.addLast(new SigfoxProtocolDecoder(SigfoxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java deleted file mode 100644 index d7836b35d..000000000 --- a/src/org/traccar/protocol/SigfoxProtocolDecoder.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.DataConverter; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { - - public SigfoxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - JsonObject json = Json.createReader(new StringReader(URLDecoder.decode( - request.content().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device")); - if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.BAD_REQUEST); - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(json.getInt("time") * 1000L)); - - ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(json.getString("data"))); - try { - 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.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025); - - } else { - - getLastLocation(position, position.getDeviceTime()); - - } - } finally { - buf.release(); - } - - position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue()); - position.set(Position.KEY_INDEX, json.getInt("seqNumber")); - - sendResponse(channel, HttpResponseStatus.OK); - return position; - } - -} diff --git a/src/org/traccar/protocol/SiwiProtocol.java b/src/org/traccar/protocol/SiwiProtocol.java deleted file mode 100644 index 8963721c8..000000000 --- a/src/org/traccar/protocol/SiwiProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class SiwiProtocol extends BaseProtocol { - - public SiwiProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SiwiProtocolDecoder(SiwiProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SiwiProtocolDecoder.java b/src/org/traccar/protocol/SiwiProtocolDecoder.java deleted file mode 100644 index 6b97f5fe0..000000000 --- a/src/org/traccar/protocol/SiwiProtocolDecoder.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 SiwiProtocolDecoder extends BaseProtocolDecoder { - - public SiwiProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$").expression("[A-Z]+,") // header - .number("(d+),") // device id - .number("d+,") // unit no - .expression("([A-Z]),") // reason - .number("d+,") // command code - .number("[^,]*,") // command value - .expression("([01]),") // ignition - .expression("[01],") // power cut - .expression("[01],") // box open - .number("d+,") // message key - .number("(d+),") // odometer - .number("(d+),") // speed - .number("(d+),") // satellites - .expression("([AV]),") // valid - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(-?d+),") // altitude - .number("(d+),") // course - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .any() - .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.set(Position.KEY_EVENT, parser.next()); - position.set(Position.KEY_IGNITION, parser.next().equals("1")); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setCourse(parser.nextInt(0)); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY, "IST")); - - return position; - } - -} diff --git a/src/org/traccar/protocol/SkypatrolProtocol.java b/src/org/traccar/protocol/SkypatrolProtocol.java deleted file mode 100644 index 7c6203d86..000000000 --- a/src/org/traccar/protocol/SkypatrolProtocol.java +++ /dev/null @@ -1,33 +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.protocol; - -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class SkypatrolProtocol extends BaseProtocol { - - public SkypatrolProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java deleted file mode 100644 index 3c7ca6dc5..000000000 --- a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; - -public class SkypatrolProtocolDecoder extends BaseProtocolDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(SkypatrolProtocolDecoder.class); - - private final long defaultMask; - - public SkypatrolProtocolDecoder(Protocol protocol) { - super(protocol); - defaultMask = Context.getConfig().getInteger(getProtocolName() + ".mask"); - } - - private static double convertCoordinate(long coordinate) { - int sign = 1; - if (coordinate > 0x7fffffffL) { - sign = -1; - coordinate = 0xffffffffL - coordinate; - } - - long degrees = coordinate / 1000000; - double minutes = (coordinate % 1000000) / 10000.0; - - return sign * (degrees + minutes / 60); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int apiNumber = buf.readUnsignedShort(); - int commandType = buf.readUnsignedByte(); - int messageType = BitUtil.from(buf.readUnsignedByte(), 4); - long mask = defaultMask; - if (buf.readUnsignedByte() == 4) { - mask = buf.readUnsignedInt(); - } - - // Binary position report - if (apiNumber == 5 && commandType == 2 && messageType == 1 && BitUtil.check(mask, 0)) { - - Position position = new Position(getProtocolName()); - - if (BitUtil.check(mask, 1)) { - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - } - - String id; - if (BitUtil.check(mask, 23)) { - id = buf.toString(buf.readerIndex(), 8, StandardCharsets.US_ASCII).trim(); - buf.skipBytes(8); - } else if (BitUtil.check(mask, 2)) { - id = buf.toString(buf.readerIndex(), 22, StandardCharsets.US_ASCII).trim(); - buf.skipBytes(22); - } else { - LOGGER.warn("No device id field"); - return null; - } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - if (BitUtil.check(mask, 3)) { - position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 4)) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 5)) { - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 7)) { - buf.readUnsignedByte(); // function category - } - - DateBuilder dateBuilder = new DateBuilder(); - - if (BitUtil.check(mask, 8)) { - dateBuilder.setDateReverse( - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - } - - if (BitUtil.check(mask, 9)) { - position.setValid(buf.readUnsignedByte() == 1); // gps status - } - - if (BitUtil.check(mask, 10)) { - position.setLatitude(convertCoordinate(buf.readUnsignedInt())); - } - - if (BitUtil.check(mask, 11)) { - position.setLongitude(convertCoordinate(buf.readUnsignedInt())); - } - - if (BitUtil.check(mask, 12)) { - position.setSpeed(buf.readUnsignedShort() / 10.0); - } - - if (BitUtil.check(mask, 13)) { - position.setCourse(buf.readUnsignedShort() / 10.0); - } - - if (BitUtil.check(mask, 14)) { - dateBuilder.setTime( - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - } - - position.setTime(dateBuilder.getDate()); - - if (BitUtil.check(mask, 15)) { - position.setAltitude(buf.readMedium()); - } - - if (BitUtil.check(mask, 16)) { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - } - - if (BitUtil.check(mask, 17)) { - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); - } - - if (BitUtil.check(mask, 20)) { - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); - } - - if (BitUtil.check(mask, 21)) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - - if (BitUtil.check(mask, 22)) { - buf.skipBytes(6); // time of message generation - } - - if (BitUtil.check(mask, 24)) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - } - - if (BitUtil.check(mask, 25)) { - buf.skipBytes(18); // gps overspeed - } - - if (BitUtil.check(mask, 26)) { - buf.skipBytes(54); // cell information - } - - if (BitUtil.check(mask, 28)) { - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); - } - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/SmartSoleProtocol.java b/src/org/traccar/protocol/SmartSoleProtocol.java deleted file mode 100644 index bcf43f68b..000000000 --- a/src/org/traccar/protocol/SmartSoleProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class SmartSoleProtocol extends BaseProtocol { - - public SmartSoleProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SmartSoleProtocolDecoder(SmartSoleProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SmartSoleProtocolDecoder.java b/src/org/traccar/protocol/SmartSoleProtocolDecoder.java deleted file mode 100644 index 04920c969..000000000 --- a/src/org/traccar/protocol/SmartSoleProtocolDecoder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.Protocol; -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 SmartSoleProtocolDecoder extends BaseProtocolDecoder { - - public SmartSoleProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("#GTXRP=") - .number("(d+),") // imei - .number("d+,") // report type - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // longitude - .number("(-?d+.d+),") // latitude - .number("(-?d+),") // altitude - .number("(d+),") // speed - .number("([01]),") // valid - .number("(d+),") // satellites - .number("(d+.d+),") // hdop - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+.d+),") // battery - .number("(d+)") // status - .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.setFixTime(parser.nextDateTime()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setAltitude(parser.nextInt()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); - position.setValid(parser.nextInt() == 1); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - - position.setDeviceTime(parser.nextDateTime()); - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_STATUS, parser.nextInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/SmokeyProtocol.java b/src/org/traccar/protocol/SmokeyProtocol.java deleted file mode 100644 index 482c8347c..000000000 --- a/src/org/traccar/protocol/SmokeyProtocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * 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; - -public class SmokeyProtocol extends BaseProtocol { - - public SmokeyProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/org/traccar/protocol/SmokeyProtocolDecoder.java deleted file mode 100644 index 9da52e97a..000000000 --- a/src/org/traccar/protocol/SmokeyProtocolDecoder.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.time.temporal.ChronoUnit; - -public class SmokeyProtocolDecoder extends BaseProtocolDecoder { - - public SmokeyProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_DATE_RECORD = 0; - public static final int MSG_DATE_RECORD_ACK = 1; - - private static void sendResponse( - Channel channel, SocketAddress remoteAddress, ByteBuf id, int index, int report) { - - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeBytes("SM".getBytes(StandardCharsets.US_ASCII)); - response.writeByte(3); // protocol version - response.writeByte(MSG_DATE_RECORD_ACK); - response.writeBytes(id); - response.writeInt( - (int) ChronoUnit.SECONDS.between(Instant.parse("2000-01-01T00:00:00.00Z"), Instant.now())); - response.writeByte(index); - response.writeByte(report - 0x200); - - short checksum = (short) 0xF5A0; - for (int i = 0; i < response.readableBytes(); i += 2) { - checksum ^= response.getShortLE(i); - } - response.writeShort(checksum); - - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedByte(); // protocol version - - int type = buf.readUnsignedByte(); - - ByteBuf id = buf.readSlice(8); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); - if (deviceSession == null) { - return null; - } - - if (type == MSG_DATE_RECORD) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_FW, buf.readUnsignedShort()); - - int status = buf.readUnsignedShort(); - position.set(Position.KEY_STATUS, status); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(2000, 1, 1).addSeconds(buf.readUnsignedInt()); - - getLastLocation(position, dateBuilder.getDate()); - - int index = buf.readUnsignedByte(); - position.set(Position.KEY_INDEX, index); - - int report = buf.readUnsignedShort(); - - buf.readUnsignedShort(); // length - - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); - - Network network = new Network(); - - if (report != 0x0203) { - - int count = 1; - if (report != 0x0200) { - count = buf.readUnsignedByte(); - } - - for (int i = 0; i < count; i++) { - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedShort(); - int lac = buf.readUnsignedShort(); - int cid = buf.readUnsignedShort(); - if (i == 0) { - buf.readByte(); // timing advance - } - int rssi = buf.readByte(); - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); - } - - } - - if (report == 0x0202 || report == 0x0203) { - - int count = buf.readUnsignedByte(); - - for (int i = 0; i < count; i++) { - buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0) + 1); // ssid - - String mac = String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - - network.addWifiAccessPoint(WifiAccessPoint.from(mac, buf.readByte())); - } - - } - - position.setNetwork(network); - - sendResponse(channel, remoteAddress, id, index, report); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/SpotProtocol.java b/src/org/traccar/protocol/SpotProtocol.java deleted file mode 100644 index bbf0e8d8a..000000000 --- a/src/org/traccar/protocol/SpotProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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.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; - -public class SpotProtocol extends BaseProtocol { - - public SpotProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); - pipeline.addLast(new SpotProtocolDecoder(SpotProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SpotProtocolDecoder.java b/src/org/traccar/protocol/SpotProtocolDecoder.java deleted file mode 100644 index da36c2048..000000000 --- a/src/org/traccar/protocol/SpotProtocolDecoder.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@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 com.fasterxml.jackson.databind.util.ByteBufferBackedInputStream; -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.Protocol; -import org.traccar.helper.DateUtil; -import org.traccar.model.Position; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import java.net.SocketAddress; -import java.util.LinkedList; -import java.util.List; - -public class SpotProtocolDecoder extends BaseHttpProtocolDecoder { - - private DocumentBuilder documentBuilder; - private XPath xPath; - private XPathExpression messageExpression; - - public SpotProtocolDecoder(Protocol protocol) { - super(protocol); - try { - DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); - builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - builderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); - builderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - builderFactory.setXIncludeAware(false); - builderFactory.setExpandEntityReferences(false); - documentBuilder = builderFactory.newDocumentBuilder(); - xPath = XPathFactory.newInstance().newXPath(); - messageExpression = xPath.compile("//messageList/message"); - } catch (ParserConfigurationException | XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - FullHttpRequest request = (FullHttpRequest) msg; - - Document document = documentBuilder.parse(new ByteBufferBackedInputStream(request.content().nioBuffer())); - NodeList nodes = (NodeList) messageExpression.evaluate(document, XPathConstants.NODESET); - - List<Position> positions = new LinkedList<>(); - - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, xPath.evaluate("esnName", node)); - if (deviceSession != null) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - position.setTime(DateUtil.parseDate(xPath.evaluate("timestamp", node))); - position.setLatitude(Double.parseDouble(xPath.evaluate("latitude", node))); - position.setLongitude(Double.parseDouble(xPath.evaluate("longitude", node))); - - position.set(Position.KEY_EVENT, xPath.evaluate("messageType", node)); - - positions.add(position); - - } - } - - sendResponse(channel, HttpResponseStatus.OK); - return positions; - } - -} diff --git a/src/org/traccar/protocol/StarLinkProtocol.java b/src/org/traccar/protocol/StarLinkProtocol.java deleted file mode 100644 index 5630722ee..000000000 --- a/src/org/traccar/protocol/StarLinkProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class StarLinkProtocol extends BaseProtocol { - - public StarLinkProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StarLinkProtocolDecoder(StarLinkProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java deleted file mode 100644 index ed5f81c1c..000000000 --- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.TimeZone; -import java.util.regex.Pattern; - -public class StarLinkProtocolDecoder extends BaseProtocolDecoder { - - private String[] dataTags; - private DateFormat dateFormat; - - public StarLinkProtocolDecoder(Protocol protocol) { - super(protocol); - - String format = Context.getConfig().getString( - getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," - + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#"); - dataTags = format.split(","); - - dateFormat = new SimpleDateFormat( - Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression(".") // protocol head - .text("SLU") // message head - .number("(x{6}|d{15}),") // id - .number("(d+),") // type - .number("(d+),") // index - .expression("(.+)") // data - .text("*") - .number("xx") // checksum - .compile(); - - public static final int MSG_EVENT_REPORT = 6; - - private double parseCoordinate(String value) { - int minutesIndex = value.indexOf('.') - 2; - double result = Double.parseDouble(value.substring(1, minutesIndex)); - result += Double.parseDouble(value.substring(minutesIndex)) / 60; - return value.charAt(0) == '+' ? result : -result; - } - - private String decodeAlarm(int event) { - switch (event) { - case 6: - return Position.ALARM_OVERSPEED; - case 7: - return Position.ALARM_GEOFENCE_ENTER; - case 8: - return Position.ALARM_GEOFENCE_EXIT; - case 9: - return Position.ALARM_POWER_CUT; - case 11: - return Position.ALARM_LOW_BATTERY; - case 26: - return Position.ALARM_TOW; - case 36: - return Position.ALARM_SOS; - case 42: - return Position.ALARM_JAMMING; - default: - return null; - } - } - - @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; - } - - int type = parser.nextInt(0); - if (type != MSG_EVENT_REPORT) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - - position.set(Position.KEY_INDEX, parser.nextInt(0)); - - String[] data = parser.next().split(","); - Integer lac = null, cid = null; - int event = 0; - - for (int i = 0; i < Math.min(data.length, dataTags.length); i++) { - if (data[i].isEmpty()) { - continue; - } - switch (dataTags[i]) { - case "#EDT#": - position.setDeviceTime(dateFormat.parse(data[i])); - break; - case "#EID#": - event = Integer.parseInt(data[i]); - position.set(Position.KEY_ALARM, decodeAlarm(event)); - position.set(Position.KEY_EVENT, event); - break; - case "#PDT#": - position.setFixTime(dateFormat.parse(data[i])); - break; - case "#LAT#": - position.setLatitude(parseCoordinate(data[i])); - break; - case "#LONG#": - position.setLongitude(parseCoordinate(data[i])); - break; - case "#SPD#": - position.setSpeed(Double.parseDouble(data[i])); - break; - case "#HEAD#": - position.setCourse(Integer.parseInt(data[i])); - break; - case "#ODO#": - position.set(Position.KEY_ODOMETER, Long.parseLong(data[i]) * 1000); - break; - case "#IN1#": - position.set(Position.PREFIX_IN + 1, Integer.parseInt(data[i])); - break; - case "#IN2#": - position.set(Position.PREFIX_IN + 2, Integer.parseInt(data[i])); - break; - case "#IN3#": - position.set(Position.PREFIX_IN + 3, Integer.parseInt(data[i])); - break; - case "#IN4#": - position.set(Position.PREFIX_IN + 4, Integer.parseInt(data[i])); - break; - case "#OUT1#": - position.set(Position.PREFIX_OUT + 1, Integer.parseInt(data[i])); - break; - case "#OUT2#": - position.set(Position.PREFIX_OUT + 2, Integer.parseInt(data[i])); - break; - case "#OUT3#": - position.set(Position.PREFIX_OUT + 3, Integer.parseInt(data[i])); - break; - case "#OUT4#": - position.set(Position.PREFIX_OUT + 4, Integer.parseInt(data[i])); - break; - case "#LAC#": - if (!data[i].isEmpty()) { - lac = Integer.parseInt(data[i]); - } - break; - case "#CID#": - if (!data[i].isEmpty()) { - cid = Integer.parseInt(data[i]); - } - break; - case "#VIN#": - position.set(Position.KEY_POWER, Double.parseDouble(data[i])); - break; - case "#VBAT#": - position.set(Position.KEY_BATTERY, Double.parseDouble(data[i])); - break; - case "#DEST#": - position.set("destination", data[i]); - break; - case "#IGN#": - position.set(Position.KEY_IGNITION, data[i].equals("1")); - break; - case "#ENG#": - position.set("engine", data[i].equals("1")); - break; - default: - break; - } - } - - if (position.getFixTime() == null) { - getLastLocation(position, null); - } - - if (lac != null && cid != null) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); - } - - if (event == 20) { - String rfid = data[data.length - 1]; - if (rfid.matches("0+")) { - rfid = data[data.length - 2]; - } - position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/Stl060FrameDecoder.java b/src/org/traccar/protocol/Stl060FrameDecoder.java deleted file mode 100644 index f72474e2b..000000000 --- a/src/org/traccar/protocol/Stl060FrameDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - * 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.ChannelHandlerContext; -import org.traccar.CharacterDelimiterFrameDecoder; - -public class Stl060FrameDecoder extends CharacterDelimiterFrameDecoder { - - public Stl060FrameDecoder(int maxFrameLength) { - super(maxFrameLength, '#'); - } - - @Override - protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { - - ByteBuf result = (ByteBuf) super.decode(ctx, buf); - - if (result != null) { - - int index = result.indexOf(result.readerIndex(), result.writerIndex(), (byte) '$'); - if (index == -1) { - return result; - } else { - result.skipBytes(index); - return result.readRetainedSlice(result.readableBytes()); - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Stl060Protocol.java b/src/org/traccar/protocol/Stl060Protocol.java deleted file mode 100644 index 2711e936b..000000000 --- a/src/org/traccar/protocol/Stl060Protocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class Stl060Protocol extends BaseProtocol { - - public Stl060Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Stl060FrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Stl060ProtocolDecoder(Stl060Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java deleted file mode 100644 index 7b0055aa1..000000000 --- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class Stl060ProtocolDecoder extends BaseProtocolDecoder { - - public Stl060ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .any() - .text("$1,") - .number("(d+),") // imei - .text("D001,") // type - .expression("[^,]*,") // vehicle - .number("(dd)/(dd)/(dd),") // date (dd/mm/yy) - .number("(dd):(dd):(dd),") // time (hh:mm:ss) - .number("(dd)(dd).?(d+)([NS]),") // latitude - .number("(ddd)(dd).?(d+)([EW]),") // longitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .groupBegin() - .number("(d+),") // odometer - .number("(d+),") // Ignition - .number("(d+),") // di1 - .number("(d+),") // di2 - .number("(d+),") // fuel - .or() - .expression("([01]),") // charging - .expression("([01]),") // ignition - .expression("0,0,") // reserved - .number("(d+),") // di - .expression("([^,]+),") // rfid - .number("(d+),") // odometer - .number("(d+),") // temperature - .number("(d+),") // fuel - .expression("([01]),") // accelerometer - .expression("([01]),") // do1 - .expression("([01]),") // do2 - .groupEnd() - .expression("([AV])") // validity - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - // Old format - if (parser.hasNext(5)) { - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - position.set(Position.KEY_INPUT, parser.nextInt(0) + parser.nextInt(0) << 1); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); - } - - // New format - if (parser.hasNext(10)) { - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); - position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); - position.set(Position.KEY_INPUT, parser.nextInt(0)); - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); - position.set(Position.KEY_ACCELERATION, parser.nextInt(0) == 1); - position.set(Position.KEY_OUTPUT, parser.nextInt(0) + parser.nextInt(0) << 1); - } - - position.setValid(parser.next().equals("A")); - - return position; - } - -} diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java deleted file mode 100644 index 29ae114e7..000000000 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class SuntechProtocol extends BaseProtocol { - - public SuntechProtocol() { - setSupportedDataCommands( - Command.TYPE_OUTPUT_CONTROL, - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SuntechProtocolEncoder()); - pipeline.addLast(new SuntechProtocolDecoder(SuntechProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java deleted file mode 100644 index 922431021..000000000 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright 2013 - 2019 Anton Tananaev (anton@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.Protocol; -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.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -public class SuntechProtocolDecoder extends BaseProtocolDecoder { - - private int protocolType; - private boolean hbm; - private boolean includeAdc; - private boolean includeTemp; - - public SuntechProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public void setProtocolType(int protocolType) { - this.protocolType = protocolType; - } - - public int getProtocolType(long deviceId) { - return Context.getIdentityManager().lookupAttributeInteger( - deviceId, getProtocolName() + ".protocolType", protocolType, true); - } - - public void setHbm(boolean hbm) { - this.hbm = hbm; - } - - public boolean isHbm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".hbm", hbm, true); - } - - public void setIncludeAdc(boolean includeAdc) { - this.includeAdc = includeAdc; - } - - public boolean isIncludeAdc(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeAdc", includeAdc, true); - } - - public void setIncludeTemp(boolean includeTemp) { - this.includeTemp = includeTemp; - } - - public boolean isIncludeTemp(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeTemp", includeTemp, true); - } - - private Position decode9( - Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { - int index = 1; - - String type = values[index++]; - - if (!type.equals("Location") && !type.equals("Emergency") && !type.equals("Alert")) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (type.equals("Emergency") || type.equals("Alert")) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - - if (!type.equals("Alert") || getProtocolType(deviceSession.getDeviceId()) == 0) { - position.set(Position.KEY_VERSION_FW, values[index++]); - } - - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(values[index++] + values[index++])); - - if (getProtocolType(deviceSession.getDeviceId()) == 1) { - index += 1; // cell - } - - position.setLatitude(Double.parseDouble(values[index++])); - position.setLongitude(Double.parseDouble(values[index++])); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - position.setCourse(Double.parseDouble(values[index++])); - - position.setValid(values[index++].equals("1")); - - if (getProtocolType(deviceSession.getDeviceId()) == 1) { - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); - } - - return position; - } - - private String decodeEmergency(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 2: - return Position.ALARM_PARKING; - case 3: - return Position.ALARM_POWER_CUT; - case 5: - case 6: - return Position.ALARM_DOOR; - case 7: - return Position.ALARM_MOVEMENT; - case 8: - return Position.ALARM_SHOCK; - default: - return null; - } - } - - private String decodeAlert(int value) { - switch (value) { - case 1: - return Position.ALARM_OVERSPEED; - case 5: - return Position.ALARM_GEOFENCE_EXIT; - case 6: - return Position.ALARM_GEOFENCE_ENTER; - case 14: - return Position.ALARM_LOW_BATTERY; - case 15: - return Position.ALARM_SHOCK; - case 16: - return Position.ALARM_ACCIDENT; - case 46: - return Position.ALARM_ACCELERATION; - case 47: - return Position.ALARM_BRAKING; - case 48: - return Position.ALARM_ACCIDENT; - case 50: - return Position.ALARM_JAMMING; - default: - return null; - } - } - private Position decode4( - Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { - int index = 0; - - String type = values[index++].substring(5); - - if (!type.equals("STT") && !type.equals("ALT")) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_TYPE, type); - - position.set(Position.KEY_VERSION_FW, values[index++]); - index += 1; // model - - Network network = new Network(); - - for (int i = 0; i < 7; i++) { - int cid = Integer.parseInt(values[index++]); - int mcc = Integer.parseInt(values[index++]); - int mnc = Integer.parseInt(values[index++]); - int lac, rssi; - if (i == 0) { - rssi = Integer.parseInt(values[index++]); - lac = Integer.parseInt(values[index++]); - } else { - lac = Integer.parseInt(values[index++]); - rssi = Integer.parseInt(values[index++]); - } - index += 1; // timing advance - if (cid > 0) { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); - } - } - - position.setNetwork(network); - - position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); - position.set(Position.KEY_ARCHIVE, values[index++].equals("0") ? true : null); - position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); - position.set(Position.KEY_STATUS, Integer.parseInt(values[index++])); - - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(values[index++] + values[index++])); - - position.setLatitude(Double.parseDouble(values[index++])); - position.setLongitude(Double.parseDouble(values[index++])); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - position.setCourse(Double.parseDouble(values[index++])); - - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); - - position.setValid(values[index++].equals("1")); - - return position; - } - - private Position decode2356( - Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException { - int index = 0; - - String type = values[index++].substring(5); - - if (!type.equals("STT") && !type.equals("EMG") && !type.equals("EVT") && !type.equals("ALT")) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_TYPE, type); - - if (protocol.equals("ST300") || protocol.equals("ST500") || protocol.equals("ST600")) { - index += 1; // model - } - - position.set(Position.KEY_VERSION_FW, values[index++]); - - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(values[index++] + values[index++])); - - if (!protocol.equals("ST500")) { - long cid = Long.parseLong(values[index++], 16); - if (protocol.equals("ST600")) { - position.setNetwork(new Network(CellTower.from( - Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), - Integer.parseInt(values[index++], 16), cid, Integer.parseInt(values[index++])))); - } - } - - position.setLatitude(Double.parseDouble(values[index++])); - position.setLongitude(Double.parseDouble(values[index++])); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - position.setCourse(Double.parseDouble(values[index++])); - - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); - - position.setValid(values[index++].equals("1")); - - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); - position.set(Position.KEY_POWER, Double.parseDouble(values[index++])); - - String io = values[index++]; - if (io.length() == 6) { - position.set(Position.KEY_IGNITION, io.charAt(0) == '1'); - position.set(Position.PREFIX_IN + 1, io.charAt(1) == '1'); - position.set(Position.PREFIX_IN + 2, io.charAt(2) == '1'); - position.set(Position.PREFIX_IN + 3, io.charAt(3) == '1'); - position.set(Position.PREFIX_OUT + 1, io.charAt(4) == '1'); - position.set(Position.PREFIX_OUT + 2, io.charAt(5) == '1'); - } - - switch (type) { - case "STT": - position.set(Position.KEY_STATUS, Integer.parseInt(values[index++])); - position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); - break; - case "EMG": - position.set(Position.KEY_ALARM, decodeEmergency(Integer.parseInt(values[index++]))); - break; - case "EVT": - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); - break; - case "ALT": - position.set(Position.KEY_ALARM, decodeAlert(Integer.parseInt(values[index++]))); - break; - default: - break; - } - - if (isHbm(deviceSession.getDeviceId())) { - - if (index < values.length) { - position.set(Position.KEY_HOURS, UnitsConverter.msFromMinutes(Integer.parseInt(values[index++]))); - } - - if (index < values.length) { - position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); - } - - if (index < values.length && values[index++].equals("0")) { - position.set(Position.KEY_ARCHIVE, true); - } - - if (isIncludeAdc(deviceSession.getDeviceId())) { - for (int i = 1; i <= 3; i++) { - if (!values[index++].isEmpty()) { - position.set(Position.PREFIX_ADC + i, Double.parseDouble(values[index - 1])); - } - } - } - - if (values.length - index >= 2) { - String driverUniqueId = values[index++]; - if (values[index++].equals("1") && !driverUniqueId.isEmpty()) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId); - } - } - - if (isIncludeTemp(deviceSession.getDeviceId())) { - for (int i = 1; i <= 3; i++) { - String temperature = values[index++]; - String value = temperature.substring(temperature.indexOf(':') + 1); - if (!value.isEmpty()) { - position.set(Position.PREFIX_TEMP + i, Double.parseDouble(value)); - } - } - - } - - } - - return position; - } - - private Position decodeUniversal( - Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { - int index = 0; - - String type = values[index++]; - - if (!type.equals("STT")) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_TYPE, type); - - int mask = Integer.parseInt(values[index++], 16); - - if (BitUtil.check(mask, 1)) { - index += 1; // model - } - - if (BitUtil.check(mask, 2)) { - position.set(Position.KEY_VERSION_FW, values[index++]); - } - - if (BitUtil.check(mask, 3) && values[index++].equals("0")) { - position.set(Position.KEY_ARCHIVE, true); - } - - if (BitUtil.check(mask, 4) && BitUtil.check(mask, 5)) { - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - position.setTime(dateFormat.parse(values[index++] + values[index++])); - } - - if (BitUtil.check(mask, 6)) { - index += 1; // cell - } - - if (BitUtil.check(mask, 7)) { - index += 1; // mcc - } - - if (BitUtil.check(mask, 8)) { - index += 1; // mnc - } - - if (BitUtil.check(mask, 9)) { - index += 1; // lac - } - - if (BitUtil.check(mask, 10)) { - position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); - } - - if (BitUtil.check(mask, 11)) { - position.setLatitude(Double.parseDouble(values[index++])); - } - - if (BitUtil.check(mask, 12)) { - position.setLongitude(Double.parseDouble(values[index++])); - } - - if (BitUtil.check(mask, 13)) { - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); - } - - if (BitUtil.check(mask, 14)) { - position.setCourse(Double.parseDouble(values[index++])); - } - - if (BitUtil.check(mask, 15)) { - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); - } - - if (BitUtil.check(mask, 16)) { - position.setValid(values[index++].equals("1")); - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String[] values = ((String) msg).split(";"); - - if (values[0].length() < 5) { - return decodeUniversal(channel, remoteAddress, values); - } else if (values[0].startsWith("ST9")) { - return decode9(channel, remoteAddress, values); - } else if (values[0].startsWith("ST4")) { - return decode4(channel, remoteAddress, values); - } else { - return decode2356(channel, remoteAddress, values[0].substring(0, 5), values); - } - } - -} diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java deleted file mode 100644 index 90fa4aa39..000000000 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.model.Command; - -public class SuntechProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "SA200CMD;{%s};02;Reboot\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_OUTPUT_CONTROL: - if (command.getAttributes().containsKey(Command.KEY_DATA)) { - if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - return formatCommand(command, "SA200CMD;{%s};02;Enable{%s}\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); - } else { - return formatCommand(command, "SA200CMD;{%s};02;Disable{%s}\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); - } - } - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "SA200CMD;{%s};02;Disable1\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "SA200CMD;{%s};02;Enable2\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "SA200CMD;{%s};02;Disable2\r", Command.KEY_UNIQUE_ID); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/SupermateProtocol.java b/src/org/traccar/protocol/SupermateProtocol.java deleted file mode 100644 index 46625ddc7..000000000 --- a/src/org/traccar/protocol/SupermateProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class SupermateProtocol extends BaseProtocol { - - public SupermateProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new SupermateProtocolDecoder(SupermateProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/SupermateProtocolDecoder.java b/src/org/traccar/protocol/SupermateProtocolDecoder.java deleted file mode 100644 index 40a25bb91..000000000 --- a/src/org/traccar/protocol/SupermateProtocolDecoder.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.Calendar; -import java.util.regex.Pattern; - -public class SupermateProtocolDecoder extends BaseProtocolDecoder { - - public SupermateProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("d+:") // header - .number("(d+):") // imei - .number("d+:").text("*,") - .number("(d+),") // command id - .expression("([^,]{2}),") // command - .expression("([AV]),") // validity - .number("(xx)(xx)(xx),") // date (yymmdd) - .number("(xx)(xx)(xx),") // time (hhmmss) - .number("(x)(x{7}),") // latitude - .number("(x)(x{7}),") // longitude - .number("(x{4}),") // speed - .number("(x{4}),") // course - .number("(x{12}),") // status - .number("(x+),") // signal - .number("(d+),") // power - .number("(x{4}),") // oil - .number("(x+)?") // odometer - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - String imei = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set("commandId", parser.next()); - position.set(Position.KEY_COMMAND, parser.next()); - - position.setValid(parser.next().equals("A")); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextHexInt(0), parser.nextHexInt(0), parser.nextHexInt(0)) - .setTime(parser.nextHexInt(0), parser.nextHexInt(0), parser.nextHexInt(0)); - position.setTime(dateBuilder.getDate()); - - if (parser.nextHexInt(0) == 8) { - position.setLatitude(-parser.nextHexInt(0) / 600000.0); - } else { - position.setLatitude(parser.nextHexInt(0) / 600000.0); - } - - if (parser.nextHexInt(0) == 8) { - position.setLongitude(-parser.nextHexInt(0) / 600000.0); - } else { - position.setLongitude(parser.nextHexInt(0) / 600000.0); - } - - position.setSpeed(parser.nextHexInt(0) / 100.0); - position.setCourse(parser.nextHexInt(0) / 100.0); - - position.set(Position.KEY_STATUS, parser.next()); - position.set("signal", parser.next()); - position.set(Position.KEY_POWER, parser.nextDouble(0)); - position.set("oil", parser.nextHexInt(0)); - position.set(Position.KEY_ODOMETER, parser.nextHexInt(0)); - - if (channel != null) { - Calendar calendar = Calendar.getInstance(); - 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.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 deleted file mode 100644 index c6624b7d4..000000000 --- a/src/org/traccar/protocol/SviasProtocol.java +++ /dev/null @@ -1,51 +0,0 @@ -/*
- * 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 org.traccar.model.Command;
-
-public class SviasProtocol extends BaseProtocol {
-
- public SviasProtocol() {
- 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);
- addServer(new TrackerServer(false, getName()) {
- @Override
- protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]"));
- pipeline.addLast(new StringEncoder());
- pipeline.addLast(new StringDecoder());
- pipeline.addLast(new SviasProtocolEncoder());
- pipeline.addLast(new SviasProtocolDecoder(SviasProtocol.this));
- }
- });
- }
-
-}
diff --git a/src/org/traccar/protocol/SviasProtocolDecoder.java b/src/org/traccar/protocol/SviasProtocolDecoder.java deleted file mode 100644 index 978483175..000000000 --- a/src/org/traccar/protocol/SviasProtocolDecoder.java +++ /dev/null @@ -1,105 +0,0 @@ -/*
- * 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.Protocol;
-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(Protocol 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 deleted file mode 100644 index 9fce57223..000000000 --- a/src/org/traccar/protocol/SviasProtocolEncoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/*
- * 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.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:
- return null;
- }
- }
-
-}
diff --git a/src/org/traccar/protocol/T55Protocol.java b/src/org/traccar/protocol/T55Protocol.java deleted file mode 100644 index f5ec19094..000000000 --- a/src/org/traccar/protocol/T55Protocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -public class T55Protocol extends BaseProtocol { - - public T55Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java deleted file mode 100644 index ba231a635..000000000 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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.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.Protocol; -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; - -public class T55ProtocolDecoder extends BaseProtocolDecoder { - - public T55ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_GPRMC = new PatternBuilder() - .text("$GPRMC,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d{2,3})(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("[^*]+") - .text("*") - .expression("[^,]+") - .number(",(d+)") // satellites - .number(",(d+)") // imei - .expression(",([01])") // ignition - .number(",(d+)") // fuel - .number(",(d+)").optional(7) // battery - .number("((?:,d+)+)?") // parameters - .any() - .compile(); - - private static final Pattern PATTERN_GPGGA = new PatternBuilder() - .text("$GPGGA,") - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .expression("([EW]),") - .any() - .compile(); - - private static final Pattern PATTERN_GPRMA = new PatternBuilder() - .text("$GPRMA,") - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),,,") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .any() - .compile(); - - private static final Pattern PATTERN_TRCCR = new PatternBuilder() - .text("$TRCCR,") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd).?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(d+.d+),") // speed - .number("(d+.d+),") // course - .number("(-?d+.d+),") // altitude - .number("(d+.?d*),") // battery - .any() - .compile(); - - private Position position = null; - - private Position decodeGprmc( - DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - - if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && Context.getIdentityManager().lookupAttributeBoolean( - deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) { - channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); - } - - Parser parser = new Parser(PATTERN_GPRMC, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - if (deviceSession != null) { - position.setDeviceId(deviceSession.getDeviceId()); - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - if (parser.hasNext(5)) { - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_IGNITION, parser.hasNext() && parser.next().equals("1")); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt()); - } - - if (parser.hasNext()) { - String[] parameters = parser.next().split(","); - for (int i = 1; i < parameters.length; i++) { - position.set(Position.PREFIX_IO + i, parameters[i]); - } - } - - if (deviceSession != null) { - return position; - } else { - this.position = position; // save position - return null; - } - } - - private Position decodeGpgga(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN_GPGGA, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setCurrentDate() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - return position; - } - - private Position decodeGprma(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN_GPRMA, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date()); - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - return position; - } - - private Position decodeTrccr(DeviceSession deviceSession, String sentence) { - - Parser parser = new Parser(PATTERN_TRCCR, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - DeviceSession deviceSession; - - if (!sentence.startsWith("$") && sentence.contains("$")) { - int index = sentence.indexOf("$"); - String id = sentence.substring(0, index); - if (id.endsWith(",")) { - id = id.substring(0, id.length() - 1); - } else if (id.endsWith("/")) { - id = id.substring(id.indexOf('/') + 1, id.length() - 1); - } - deviceSession = getDeviceSession(channel, remoteAddress, id); - sentence = sentence.substring(index); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - - if (sentence.startsWith("$PGID")) { - getDeviceSession(channel, remoteAddress, sentence.substring(6, sentence.length() - 3)); - } else if (sentence.startsWith("$DEVID")) { - getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.lastIndexOf('*'))); - } else if (sentence.startsWith("$PCPTI")) { - getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.indexOf(",", 7))); - } else if (sentence.startsWith("IMEI")) { - getDeviceSession(channel, remoteAddress, sentence.substring(5)); - } else if (sentence.startsWith("$IMEI")) { - getDeviceSession(channel, remoteAddress, sentence.substring(6)); - } else if (sentence.startsWith("$GPFID")) { - deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(7)); - if (deviceSession != null && position != null) { - Position position = this.position; - position.setDeviceId(deviceSession.getDeviceId()); - this.position = null; - return position; - } - } else if (sentence.matches("^[0-9A-F]+$")) { - getDeviceSession(channel, remoteAddress, sentence); - } else if (sentence.startsWith("$GPRMC")) { - return decodeGprmc(deviceSession, sentence, remoteAddress, channel); - } else if (sentence.startsWith("$GPGGA") && deviceSession != null) { - return decodeGpgga(deviceSession, sentence); - } else if (sentence.startsWith("$GPRMA") && deviceSession != null) { - return decodeGprma(deviceSession, sentence); - } else if (sentence.startsWith("$TRCCR") && deviceSession != null) { - return decodeTrccr(deviceSession, sentence); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/T57FrameDecoder.java b/src/org/traccar/protocol/T57FrameDecoder.java deleted file mode 100644 index 14ba31453..000000000 --- a/src/org/traccar/protocol/T57FrameDecoder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * 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; - -import java.nio.charset.StandardCharsets; - -public class T57FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - String type = buf.toString(buf.readerIndex() + 5, 2, StandardCharsets.US_ASCII); - int count = type.equals("F3") ? 12 : 14; - - int index = 0; - while (index >= 0 && count > 0) { - index = buf.indexOf(index + 1, buf.writerIndex(), (byte) '#'); - if (index > 0) { - count -= 1; - } - } - - 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 deleted file mode 100644 index f67f82318..000000000 --- a/src/org/traccar/protocol/T57Protocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class T57Protocol extends BaseProtocol { - - public T57Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new T57FrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new T57ProtocolDecoder(T57Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/T57ProtocolDecoder.java b/src/org/traccar/protocol/T57ProtocolDecoder.java deleted file mode 100644 index 2a3cca3e4..000000000 --- a/src/org/traccar/protocol/T57ProtocolDecoder.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class T57ProtocolDecoder extends BaseProtocolDecoder { - - public T57ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*T57#") - .number("Fd#") // type - .number("([^#]+)#") // device id - .number("(dd)(dd)(dd)#") // date (ddmmyy) - .number("(dd)(dd)(dd)#") // time (hhmmss) - .number("(dd)(dd.d+)#") // latitude - .expression("([NS])#") - .number("(ddd)(dd.d+)#") // longitude - .expression("([EW])#") - .expression("[^#]+#") - .number("(d+.d+)#") // speed - .number("(d+.d+)#") // altitude - .expression("([AV])") // valid - .number("d#") // fix type - .number("(d+.d+)#") // battery - .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.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - - position.setValid(parser.next().equals("A")); - - position.set(Position.KEY_BATTERY, parser.nextDouble()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/T800xProtocol.java b/src/org/traccar/protocol/T800xProtocol.java deleted file mode 100644 index 85749d0cf..000000000 --- a/src/org/traccar/protocol/T800xProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class T800xProtocol extends BaseProtocol { - - public T800xProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); - pipeline.addLast(new T800xProtocolEncoder()); - pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/T800xProtocolDecoder.java b/src/org/traccar/protocol/T800xProtocolDecoder.java deleted file mode 100644 index dfb286257..000000000 --- a/src/org/traccar/protocol/T800xProtocolDecoder.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.BcdUtil; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class T800xProtocolDecoder extends BaseProtocolDecoder { - - public T800xProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN = 0x01; - public static final int MSG_GPS = 0x02; - public static final int MSG_HEARTBEAT = 0x03; - public static final int MSG_ALARM = 0x04; - public static final int MSG_COMMAND = 0x81; - - private void sendResponse(Channel channel, short header, int type, int index, ByteBuf imei) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(15); - response.writeShort(header); - response.writeByte(type); - response.writeShort(response.capacity()); // length - response.writeShort(index); - response.writeBytes(imei); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private String decodeAlarm(short value) { - switch (value) { - case 1: - return Position.ALARM_POWER_CUT; - case 2: - return Position.ALARM_LOW_BATTERY; - case 3: - return Position.ALARM_SOS; - case 4: - return Position.ALARM_OVERSPEED; - case 5: - return Position.ALARM_GEOFENCE_ENTER; - case 6: - return Position.ALARM_GEOFENCE_EXIT; - case 7: - return Position.ALARM_TOW; - case 8: - case 10: - return Position.ALARM_VIBRATION; - case 21: - return Position.ALARM_JAMMING; - case 23: - return Position.ALARM_POWER_RESTORED; - case 24: - return Position.ALARM_LOW_POWER; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - short header = buf.readShort(); - int type = buf.readUnsignedByte(); - buf.readUnsignedShort(); // length - int index = buf.readUnsignedShort(); - ByteBuf imei = buf.readSlice(8); - - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, ByteBufUtil.hexDump(imei).substring(1)); - if (deviceSession == null) { - return null; - } - - sendResponse(channel, header, type, index, imei); - - if (type == MSG_GPS || type == MSG_ALARM) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, index); - - buf.readUnsignedShort(); // acc on interval - buf.readUnsignedShort(); // acc off interval - buf.readUnsignedByte(); // angle compensation - buf.readUnsignedShort(); // distance compensation - - position.set(Position.KEY_RSSI, BitUtil.to(buf.readUnsignedShort(), 7)); - - int status = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, BitUtil.to(status, 5)); - - buf.readUnsignedByte(); // gsensor manager status - buf.readUnsignedByte(); // other flags - buf.readUnsignedByte(); // heartbeat - buf.readUnsignedByte(); // relay status - buf.readUnsignedShort(); // drag alarm setting - - int io = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(io, 14)); - position.set("ac", BitUtil.check(io, 13)); - - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - - buf.readUnsignedByte(); // reserved - - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - - int battery = BcdUtil.readInteger(buf, 2); - if (battery == 0) { - battery = 100; - } - position.set(Position.KEY_BATTERY, battery); - - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - - if (BitUtil.check(status, 6)) { - - position.setValid(!BitUtil.check(status, 7)); - position.setTime(dateBuilder.getDate()); - 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()); - - int mcc = buf.readUnsignedShortLE(); - int mnc = buf.readUnsignedShortLE(); - - 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); - } - - } - - if (buf.readableBytes() >= 2) { - position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01); - } - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/T800xProtocolEncoder.java b/src/org/traccar/protocol/T800xProtocolEncoder.java deleted file mode 100644 index 1d0f3dabe..000000000 --- a/src/org/traccar/protocol/T800xProtocolEncoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolEncoder; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; - -public class T800xProtocolEncoder extends BaseProtocolEncoder { - - public static final int MODE_SETTING = 0x01; - public static final int MODE_BROADCAST = 0x02; - public static final int MODE_FORWARD = 0x03; - - private ByteBuf encodeContent(Command command, String content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeByte('#'); - buf.writeByte('#'); - buf.writeByte(T800xProtocolDecoder.MSG_COMMAND); - buf.writeShort(7 + 8 + 1 + content.length()); - buf.writeShort(1); // serial number - buf.writeBytes(DataConverter.parseHex("0" + getUniqueId(command.getDeviceId()))); - buf.writeByte(MODE_SETTING); - buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command, command.getString(Command.KEY_DATA)); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/TaipProtocol.java b/src/org/traccar/protocol/TaipProtocol.java deleted file mode 100644 index b8f40a183..000000000 --- a/src/org/traccar/protocol/TaipProtocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -public class TaipProtocol extends BaseProtocol { - - public TaipProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new TaipProtocolDecoder(TaipProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new TaipProtocolDecoder(TaipProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java deleted file mode 100644 index 8a0cb870b..000000000 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.DateUtil; -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 TaipProtocolDecoder extends BaseProtocolDecoder { - - public TaipProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .groupBegin() - .expression("R[EP]V") // type - .groupBegin() - .number("(dd)") // event - .number("(dddd)") // week - .number("(d)") // day - .groupEnd("?") - .number("(d{5})") // seconds - .or() - .expression("(?:RGP|RCQ|RCV|RBR)") // type - .number("(dd)?") // event - .number("(dd)(dd)(dd)") // date (mmddyy) - .number("(dd)(dd)(dd)") // time (hhmmss) - .groupEnd() - .groupBegin() - .number("([-+]dd)(d{5})") // latitude - .number("([-+]ddd)(d{5})") // longitude - .or() - .number("([-+])(dd)(dd.dddd)") // latitude - .number("([-+])(ddd)(dd.dddd)") // longitude - .groupEnd() - .number("(ddd)") // speed - .number("(ddd)") // course - .groupBegin() - .number("([023])") // fix mode - .number("xx") // data age - .number("(xx)") // input - .number("(dd)") // event - .number("(dd)") // hdop - .or() - .groupBegin() - .number("(xx)") // input - .number("(xx)") // satellites - .number("(ddd)") // battery - .number("(x{8})") // odometer - .number("[01]") // gps power - .groupBegin() - .number("([023])") // fix mode - .number("(dd)") // pdop - .number("dd") // satellites - .number("xxxx") // data age - .number("[01]") // modem power - .number("[0-5]") // gsm status - .number("(dd)") // rssi - .number("([-+]dddd)") // temperature 1 - .number("xx") // seconds from last - .number("([-+]dddd)") // temperature 2 - .number("xx") // seconds from last - .groupEnd("?") - .groupEnd("?") - .groupEnd() - .any() - .compile(); - - private Date getTime(long week, long day, long seconds) { - DateBuilder dateBuilder = new DateBuilder() - .setDate(1980, 1, 6) - .addMillis(((week * 7 + day) * 24 * 60 * 60 + seconds) * 1000); - return dateBuilder.getDate(); - } - - private Date getTime(long seconds) { - DateBuilder dateBuilder = new DateBuilder(new Date()) - .setTime(0, 0, 0, 0) - .addMillis(seconds * 1000); - return DateUtil.correctDay(dateBuilder.getDate()); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - int beginIndex = sentence.indexOf('>'); - if (beginIndex != -1) { - sentence = sentence.substring(beginIndex + 1); - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - Boolean valid = null; - Integer event = null; - - if (parser.hasNext(3)) { - event = parser.nextInt(); - position.setTime(getTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0))); - } else if (parser.hasNext()) { - position.setTime(getTime(parser.nextInt(0))); - } - - if (parser.hasNext()) { - event = parser.nextInt(); - } - - if (parser.hasNext(6)) { - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - } - - if (parser.hasNext(4)) { - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG)); - } - if (parser.hasNext(6)) { - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - } - - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext(4)) { - valid = parser.nextInt() > 0; - int input = parser.nextHexInt(); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 7)); - position.set(Position.KEY_INPUT, input); - event = parser.nextInt(); - position.set(Position.KEY_HDOP, parser.nextInt()); - } - - if (parser.hasNext(4)) { - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - position.set(Position.KEY_SATELLITES, parser.nextHexInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); - } - - if (parser.hasNext(4)) { - valid = parser.nextInt() > 0; - position.set(Position.KEY_PDOP, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt() * 0.01); - position.set(Position.PREFIX_TEMP + 2, parser.nextInt() * 0.01); - } - - position.setValid(valid == null || valid); - - if (event != null) { - position.set(Position.KEY_EVENT, event); - switch (event) { - case 22: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 23: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 24: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - case 26: - case 28: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; - } - } - - String[] attributes = null; - beginIndex = sentence.indexOf(';'); - if (beginIndex != -1) { - int endIndex = sentence.indexOf('<', beginIndex); - if (endIndex == -1) { - endIndex = sentence.length(); - } - attributes = sentence.substring(beginIndex, endIndex).split(";"); - } - - return decodeAttributes(channel, remoteAddress, position, attributes); - } - - private Position decodeAttributes( - Channel channel, SocketAddress remoteAddress, Position position, String[] attributes) { - - String uniqueId = null; - DeviceSession deviceSession = null; - String messageIndex = null; - - if (attributes != null) { - for (String attribute : attributes) { - int index = attribute.indexOf('='); - if (index != -1) { - String key = attribute.substring(0, index).toLowerCase(); - String value = attribute.substring(index + 1); - switch (key) { - case "id": - uniqueId = value; - deviceSession = getDeviceSession(channel, remoteAddress, value); - if (deviceSession != null) { - position.setDeviceId(deviceSession.getDeviceId()); - } - break; - case "io": - position.set(Position.KEY_IGNITION, BitUtil.check(value.charAt(0) - '0', 0)); - position.set(Position.KEY_CHARGE, BitUtil.check(value.charAt(0) - '0', 1)); - position.set(Position.KEY_OUTPUT, value.charAt(1) - '0'); - position.set(Position.KEY_INPUT, value.charAt(2) - '0'); - break; - case "ix": - position.set(Position.PREFIX_IO + 1, value); - break; - case "ad": - position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); - break; - case "sv": - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case "bl": - position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); - break; - case "vo": - position.set(Position.KEY_ODOMETER, Long.parseLong(value)); - break; - default: - position.set(key, value); - break; - } - } else if (attribute.startsWith("#")) { - messageIndex = attribute; - } - } - } - - if (deviceSession != null) { - if (channel != null) { - if (messageIndex != null) { - String response = ">ACK;ID=" + uniqueId + ";" + messageIndex + ";*"; - response += String.format("%02X", Checksum.xor(response)) + "<"; - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } else { - channel.writeAndFlush(new NetworkMessage(uniqueId, remoteAddress)); - } - } - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TekFrameDecoder.java b/src/org/traccar/protocol/TekFrameDecoder.java deleted file mode 100644 index 44d2c590e..000000000 --- a/src/org/traccar/protocol/TekFrameDecoder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; -import org.traccar.helper.BitUtil; - -public class TekFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 17) { - return null; - } - - int length = 17 + buf.getUnsignedByte(16) + (BitUtil.from(buf.getUnsignedByte(15), 6) << 6); - if (buf.readableBytes() >= length) { - return buf.readBytes(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TekProtocol.java b/src/org/traccar/protocol/TekProtocol.java deleted file mode 100644 index c1d78e6f5..000000000 --- a/src/org/traccar/protocol/TekProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - -public class TekProtocol extends BaseProtocol { - - public TekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TekFrameDecoder()); - pipeline.addLast(new TekProtocolDecoder(TekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TekProtocolDecoder.java b/src/org/traccar/protocol/TekProtocolDecoder.java deleted file mode 100644 index a9101e65f..000000000 --- a/src/org/traccar/protocol/TekProtocolDecoder.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -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 TekProtocolDecoder extends BaseProtocolDecoder { - - public TekProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number(",d+,") - .number("(dd)(dd)(dd).d,") // time (hhmmss) - .number("(dd)(dd.d+)") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+)") // longitude - .expression("([EW]),") - .number("(d+.d+),") // hdop - .number("(d+.d+),") // altitude - .number("(d+),") // fix mode - .number("(d+.d+),") // course - .number("d+.d+,") // speed km - .number("(d+.d+),") // speed kn - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(d+),") // satellites - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // product type - buf.readUnsignedByte(); // hardware version - buf.readUnsignedByte(); // firmware version - buf.readUnsignedByte(); // contact reason - buf.readUnsignedByte(); // alarm / status - buf.readUnsignedByte(); // rssi - buf.readUnsignedByte(); // battery / status - - String imei = ByteBufUtil.hexDump(buf.readBytes(8)).substring(1); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - int type = BitUtil.to(buf.readUnsignedByte(), 6); - buf.readUnsignedByte(); // length - - if (type == 4 || type == 8) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int count = buf.readUnsignedShort(); - buf.readUnsignedByte(); // hours / tickets - buf.readUnsignedByte(); // error code - buf.readUnsignedByte(); // reserved - buf.readUnsignedByte(); // logger speed - buf.readUnsignedByte(); // login time - buf.readUnsignedByte(); // minutes - - for (int i = 0; i < count; i++) { - position.set("rssi" + (i + 1), buf.readUnsignedByte()); - position.set("temp" + (i + 1), buf.readUnsignedByte() - 30); - int data = buf.readUnsignedShort(); - position.set("src" + (i + 1), BitUtil.from(data, 10)); - position.set("ullage" + (i + 1), BitUtil.to(data, 10)); - } - - return position; - - } else if (type == 17) { - - String sentence = buf.toString(StandardCharsets.US_ASCII); - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - - position.setAltitude(parser.nextDouble()); - position.setValid(parser.nextInt() > 0); - position.setCourse(parser.nextDouble()); - position.setSpeed(parser.nextDouble()); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TelemaxProtocol.java b/src/org/traccar/protocol/TelemaxProtocol.java deleted file mode 100644 index 838da9df1..000000000 --- a/src/org/traccar/protocol/TelemaxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -public class TelemaxProtocol extends BaseProtocol { - - public TelemaxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TelemaxProtocolDecoder(TelemaxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TelemaxProtocolDecoder.java b/src/org/traccar/protocol/TelemaxProtocolDecoder.java deleted file mode 100644 index 9369ab101..000000000 --- a/src/org/traccar/protocol/TelemaxProtocolDecoder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.Protocol; -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(Protocol 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 deleted file mode 100644 index d1fef1b5b..000000000 --- a/src/org/traccar/protocol/TelicFrameDecoder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 4) { - return null; - } - - long length = buf.getUnsignedIntLE(buf.readerIndex()); - - if (length < 1024) { - if (buf.readableBytes() >= length + 4) { - buf.readUnsignedIntLE(); - return buf.readRetainedSlice((int) length); - } - } else { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); - if (endIndex >= 0) { - ByteBuf frame = buf.readRetainedSlice(endIndex - buf.readerIndex()); - buf.readByte(); - if (frame.readableBytes() > 0) { - return frame; - } - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java deleted file mode 100644 index 991befa19..000000000 --- a/src/org/traccar/protocol/TelicProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class TelicProtocol extends BaseProtocol { - - public TelicProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TelicFrameDecoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new TelicProtocolDecoder(TelicProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java deleted file mode 100644 index 6d5e8f21e..000000000 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 TelicProtocolDecoder extends BaseProtocolDecoder { - - public TelicProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("dddd") - .number("(d{6}|d{15})") // device id - .number("(d{1,2}),") // type - .number("d{12},") // event time - .number("d+,") - .number("(dd)(dd)(dd)") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .groupBegin() - .number("(ddd)(dd)(dddd),") // longitude - .number("(dd)(dd)(dddd),") // latitude - .or() - .number("(-?d+),") // longitude - .number("(-?d+),") // latitude - .groupEnd() - .number("(d),") // validity - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+)?,") // satellites - .expression("(?:[^,]*,){7}") - .number("(d+),") // battery - .any() - .compile(); - - private String decodeAlarm(int eventId) { - - switch (eventId) { - case 1: - return Position.ALARM_POWER_ON; - case 2: - return Position.ALARM_SOS; - case 5: - return Position.ALARM_POWER_OFF; - case 7: - return Position.ALARM_GEOFENCE_ENTER; - case 8: - return Position.ALARM_GEOFENCE_EXIT; - case 22: - return Position.ALARM_LOW_BATTERY; - case 25: - return Position.ALARM_MOVEMENT; - default: - return null; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - int event = parser.nextInt(0); - position.set(Position.KEY_EVENT, event); - - position.set(Position.KEY_ALARM, decodeAlarm(event)); - - if (event == 11) { - position.set(Position.KEY_IGNITION, true); - } else if (event == 12) { - position.set(Position.KEY_IGNITION, false); - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - if (parser.hasNext(6)) { - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - } - - if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble(0) / 10000); - position.setLatitude(parser.nextDouble(0) / 10000); - } - - position.setValid(parser.nextInt(0) != 1); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext()) { - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - } - - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/org/traccar/protocol/TeltonikaFrameDecoder.java deleted file mode 100644 index 4d4d79d8d..000000000 --- a/src/org/traccar/protocol/TeltonikaFrameDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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, ByteBuf buf) throws Exception { - - // Check minimum length - if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { - return null; - } - - // Read packet - int length = buf.getUnsignedShort(buf.readerIndex()); - if (length > 0) { - if (buf.readableBytes() >= (length + 2)) { - return buf.readRetainedSlice(length + 2); - } - } else { - int dataLength = buf.getInt(buf.readerIndex() + 4); - if (buf.readableBytes() >= (dataLength + 12)) { - return buf.readRetainedSlice(dataLength + 12); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java deleted file mode 100644 index eef9662d7..000000000 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class TeltonikaProtocol extends BaseProtocol { - - public TeltonikaProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TeltonikaFrameDecoder()); - pipeline.addLast(new TeltonikaProtocolEncoder()); - pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TeltonikaProtocolEncoder()); - pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java deleted file mode 100644 index 974d2c106..000000000 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright 2013 - 2019 Anton Tananaev (anton@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.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -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; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { - - private static final int IMAGE_PACKET_MAX = 2048; - - private boolean connectionless; - private boolean extended; - private Map<Long, ByteBuf> photos = new HashMap<>(); - - public void setExtended(boolean extended) { - this.extended = extended; - } - - public TeltonikaProtocolDecoder(Protocol protocol, boolean connectionless) { - super(protocol); - this.connectionless = connectionless; - this.extended = Context.getConfig().getBoolean(getProtocolName() + ".extended"); - } - - private void 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) { - ByteBuf response = Unpooled.buffer(1); - if (deviceSession != null) { - response.writeByte(1); - } else { - response.writeByte(0); - } - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - public static final int CODEC_GH3000 = 0x07; - public static final int CODEC_8 = 0x08; - public static final int CODEC_8_EXT = 0x8E; - public static final int CODEC_12 = 0x0C; - public static final int CODEC_16 = 0x10; - - private void sendImageRequest(Channel channel, SocketAddress remoteAddress, long id, int offset, int size) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeInt(0); - response.writeShort(0); - response.writeShort(19); // length - response.writeByte(CODEC_12); - response.writeByte(1); // nod - response.writeByte(0x0D); // camera - response.writeInt(11); // payload length - response.writeByte(2); // command - response.writeInt((int) id); - response.writeInt(offset); - response.writeShort(size); - response.writeByte(1); // nod - response.writeShort(0); - response.writeShort(Checksum.crc16( - Checksum.CRC16_IBM, response.nioBuffer(8, response.readableBytes() - 10))); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - private void decodeSerial(Channel channel, SocketAddress remoteAddress, Position position, ByteBuf buf) { - - getLastLocation(position, null); - - int type = buf.readUnsignedByte(); - if (type == 0x0D) { - - buf.readInt(); // length - int subtype = buf.readUnsignedByte(); - if (subtype == 0x01) { - - long photoId = buf.readUnsignedInt(); - ByteBuf photo = Unpooled.buffer(buf.readInt()); - photos.put(photoId, photo); - sendImageRequest( - channel, remoteAddress, photoId, - 0, Math.min(IMAGE_PACKET_MAX, photo.capacity())); - - } else if (subtype == 0x02) { - - long photoId = buf.readUnsignedInt(); - buf.readInt(); // offset - ByteBuf photo = photos.get(photoId); - photo.writeBytes(buf, buf.readUnsignedShort()); - if (photo.writableBytes() > 0) { - sendImageRequest( - channel, remoteAddress, photoId, - photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); - } else { - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); - photos.remove(photoId); - try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); - } finally { - photo.release(); - } - } - - } - - } else { - - position.set(Position.KEY_TYPE, type); - position.set(Position.KEY_RESULT, buf.readSlice(buf.readInt()).toString(StandardCharsets.US_ASCII)); - - } - } - - private long readValue(ByteBuf buf, int length, boolean signed) { - switch (length) { - case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); - case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); - case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); - default: - return buf.readLong(); - } - } - - private void decodeOtherParameter(Position position, int id, ByteBuf buf, int length) { - switch (id) { - case 1: - case 2: - case 3: - case 4: - position.set("di" + id, readValue(buf, length, false)); - break; - case 9: - position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); - break; - case 17: - position.set("axisX", readValue(buf, length, true)); - break; - case 18: - position.set("axisY", readValue(buf, length, true)); - break; - case 19: - position.set("axisZ", readValue(buf, length, true)); - break; - case 21: - position.set(Position.KEY_RSSI, readValue(buf, length, false)); - break; - case 25: - case 26: - case 27: - case 28: - position.set(Position.PREFIX_TEMP + (id - 24), readValue(buf, length, true) * 0.1); - break; - case 66: - position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 69: - position.set("gpsStatus", readValue(buf, length, false)); - break; - case 72: - case 73: - case 74: - position.set(Position.PREFIX_TEMP + (id - 71), readValue(buf, length, true) * 0.1); - break; - case 78: - long driverUniqueId = readValue(buf, length, false); - if (driverUniqueId != 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); - } - break; - 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; - case 180: - position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); - break; - case 181: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); - break; - 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; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); - break; - case 241: - position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } - } - - 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)); - break; - case 2: - position.set("usbConnected", readValue(buf, length, false) == 1); - break; - case 5: - position.set("uptime", readValue(buf, length, false)); - break; - case 20: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); - break; - case 21: - position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); - break; - case 22: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 221: - position.set("button", readValue(buf, length, false)); - break; - case 222: - if (readValue(buf, length, false) == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - break; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); - break; - case 244: - position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } - } - - private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, id, buf, length); - } else { - decodeOtherParameter(position, id, buf, length); - } - } - - private void decodeNetwork(Position position) { - long cid = position.getLong(Position.PREFIX_IO + 205); - int lac = position.getInteger(Position.PREFIX_IO + 206); - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromLacCid(lac, cid); - long operator = position.getInteger(Position.KEY_OPERATOR); - if (operator != 0) { - cellTower.setOperator(operator); - } - position.setNetwork(new Network(cellTower)); - } - } - - private int readExtByte(ByteBuf buf, int codec, int... codecs) { - boolean ext = false; - for (int c : codecs) { - if (codec == c) { - ext = true; - break; - } - } - if (ext) { - return buf.readUnsignedShort(); - } else { - return buf.readUnsignedByte(); - } - } - - private void decodeLocation(Position position, ByteBuf buf, int codec) { - - int globalMask = 0x0f; - - if (codec == CODEC_GH3000) { - - long time = buf.readUnsignedInt() & 0x3fffffff; - time += 1167609600; // 2007-01-01 00:00:00 - - globalMask = buf.readUnsignedByte(); - if (BitUtil.check(globalMask, 0)) { - - position.setTime(new Date(time * 1000)); - - int locationMask = buf.readUnsignedByte(); - - if (BitUtil.check(locationMask, 0)) { - position.setLatitude(buf.readFloat()); - position.setLongitude(buf.readFloat()); - } - - if (BitUtil.check(locationMask, 1)) { - position.setAltitude(buf.readUnsignedShort()); - } - - if (BitUtil.check(locationMask, 2)) { - position.setCourse(buf.readUnsignedByte() * 360.0 / 256); - } - - if (BitUtil.check(locationMask, 3)) { - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - } - - if (BitUtil.check(locationMask, 4)) { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - } - - if (BitUtil.check(locationMask, 5)) { - CellTower cellTower = CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()); - - if (BitUtil.check(locationMask, 6)) { - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - } - - if (BitUtil.check(locationMask, 7)) { - cellTower.setOperator(buf.readUnsignedInt()); - } - - position.setNetwork(new Network(cellTower)); - - } else { - if (BitUtil.check(locationMask, 6)) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } - if (BitUtil.check(locationMask, 7)) { - position.set(Position.KEY_OPERATOR, buf.readUnsignedInt()); - } - } - - } else { - - getLastLocation(position, new Date(time * 1000)); - - } - - } else { - - position.setTime(new Date(buf.readLong())); - - position.set("priority", buf.readUnsignedByte()); - - position.setLongitude(buf.readInt() / 10000000.0); - position.setLatitude(buf.readInt() / 10000000.0); - position.setAltitude(buf.readShort()); - position.setCourse(buf.readUnsignedShort()); - - int satellites = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, satellites); - - position.setValid(satellites != 0); - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - - position.set(Position.KEY_EVENT, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16)); - if (codec == CODEC_16) { - buf.readUnsignedByte(); // generation type - } - - readExtByte(buf, codec, CODEC_8_EXT); // total IO data records - - } - - // Read 1 byte data - if (BitUtil.check(globalMask, 1)) { - int cnt = readExtByte(buf, codec, CODEC_8_EXT); - for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec); - } - } - - // Read 2 byte data - if (BitUtil.check(globalMask, 2)) { - int cnt = readExtByte(buf, codec, CODEC_8_EXT); - for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec); - } - } - - // Read 4 byte data - if (BitUtil.check(globalMask, 3)) { - int cnt = readExtByte(buf, codec, CODEC_8_EXT); - for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec); - } - } - - // Read 8 byte data - if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { - int cnt = readExtByte(buf, codec, CODEC_8_EXT); - for (int j = 0; j < cnt; j++) { - decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8); - } - } - - // Read 16 byte data - if (extended) { - int cnt = readExtByte(buf, codec, CODEC_8_EXT); - for (int j = 0; j < cnt; j++) { - int id = readExtByte(buf, codec, CODEC_8_EXT, CODEC_16); - position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(16))); - } - } - - // Read X byte data - if (codec == CODEC_8_EXT) { - int cnt = buf.readUnsignedShort(); - for (int j = 0; j < cnt; j++) { - int id = buf.readUnsignedShort(); - int length = buf.readUnsignedShort(); - if (id == 256) { - position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); - } else { - position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(length))); - } - } - } - - decodeNetwork(position); - - } - - private List<Position> parseData( - Channel channel, SocketAddress remoteAddress, ByteBuf buf, int locationPacketId, String... imei) { - List<Position> positions = new LinkedList<>(); - - if (!connectionless) { - buf.readUnsignedInt(); // data length - } - - int codec = buf.readUnsignedByte(); - int count = buf.readUnsignedByte(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - - if (deviceSession == null) { - return null; - } - - for (int i = 0; i < count; i++) { - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - - if (codec == CODEC_12) { - decodeSerial(channel, remoteAddress, position, buf); - } else { - decodeLocation(position, buf, codec); - } - - if (!position.getOutdated() || !position.getAttributes().isEmpty()) { - positions.add(position); - } - } - - if (channel != null) { - if (connectionless) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(5); - response.writeShort(0); - response.writeByte(0x01); - response.writeByte(locationPacketId); - response.writeByte(count); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } else { - ByteBuf response = Unpooled.buffer(); - response.writeInt(count); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - return positions.isEmpty() ? null : positions; - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (connectionless) { - return decodeUdp(channel, remoteAddress, buf); - } else { - return decodeTcp(channel, remoteAddress, buf); - } - } - - private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { - - if (buf.getUnsignedShort(0) > 0) { - parseIdentification(channel, remoteAddress, buf); - } else { - buf.skipBytes(4); - return parseData(channel, remoteAddress, buf, 0); - } - - return null; - } - - 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.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 deleted file mode 100644 index 944cec024..000000000 --- a/src/org/traccar/protocol/TeltonikaProtocolEncoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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.helper.Checksum; -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 ByteBuf encodeContent(String content) { - - ByteBuf buf = Unpooled.buffer(); - - buf.writeInt(0); - buf.writeInt(content.length() + 10); - buf.writeByte(TeltonikaProtocolDecoder.CODEC_12); - buf.writeByte(1); // quantity - buf.writeByte(5); // type - buf.writeInt(content.length() + 2); - buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); - buf.writeByte('\r'); - buf.writeByte('\n'); - buf.writeByte(1); // quantity - buf.writeInt(Checksum.crc16(Checksum.CRC16_IBM, buf.nioBuffer(8, buf.writerIndex() - 8))); - - return buf; - } - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command.getString(Command.KEY_DATA)); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/ThinkRaceProtocol.java b/src/org/traccar/protocol/ThinkRaceProtocol.java deleted file mode 100644 index ca1237cef..000000000 --- a/src/org/traccar/protocol/ThinkRaceProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class ThinkRaceProtocol extends BaseProtocol { - - public ThinkRaceProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); - pipeline.addLast(new ThinkRaceProtocolDecoder(ThinkRaceProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java deleted file mode 100644 index 0928b25e0..000000000 --- a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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 ThinkRaceProtocolDecoder extends BaseProtocolDecoder { - - public ThinkRaceProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN = 0x80; - public static final int MSG_GPS = 0x90; - - private static double convertCoordinate(long raw, boolean negative) { - long degrees = raw / 1000000; - double minutes = (raw % 1000000) * 0.0001; - double result = degrees + minutes / 60; - if (negative) { - result = -result; - } - return result; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - ByteBuf id = buf.readSlice(12); - buf.readUnsignedByte(); // separator - int type = buf.readUnsignedByte(); - buf.readUnsignedShort(); // length - - if (type == MSG_LOGIN) { - - int command = buf.readUnsignedByte(); // 0x00 - heartbeat - - if (command == 0x01) { - String imei = buf.toString(buf.readerIndex(), 15, StandardCharsets.US_ASCII); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(0x48); response.writeByte(0x52); // header - response.writeBytes(id); - response.writeByte(0x2c); // separator - response.writeByte(type); - response.writeShort(0x0002); // length - response.writeShort(0x8000); - response.writeShort(0x0000); // checksum - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - } else if (type == MSG_GPS) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - int flags = buf.readUnsignedByte(); - - position.setValid(true); - position.setLatitude(convertCoordinate(buf.readUnsignedInt(), !BitUtil.check(flags, 0))); - position.setLongitude(convertCoordinate(buf.readUnsignedInt(), !BitUtil.check(flags, 1))); - - position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedByte()); - - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Tk102Protocol.java b/src/org/traccar/protocol/Tk102Protocol.java deleted file mode 100644 index 9f2463cd6..000000000 --- a/src/org/traccar/protocol/Tk102Protocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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; - -public class Tk102Protocol extends BaseProtocol { - - public Tk102Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); - pipeline.addLast(new Tk102ProtocolDecoder(Tk102Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/org/traccar/protocol/Tk102ProtocolDecoder.java deleted file mode 100644 index da0c6928b..000000000 --- a/src/org/traccar/protocol/Tk102ProtocolDecoder.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 Tk102ProtocolDecoder extends BaseProtocolDecoder { - - public Tk102ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_LOGIN_REQUEST = 0x80; - public static final int MSG_LOGIN_REQUEST_2 = 0x21; - public static final int MSG_LOGIN_RESPONSE = 0x00; - public static final int MSG_HEARTBEAT_REQUEST = 0xF0; - public static final int MSG_HEARTBEAT_RESPONSE = 0xFF; - public static final int MSG_REPORT_ONCE = 0x90; - public static final int MSG_REPORT_INTERVAL = 0x93; - - public static final int MODE_GPRS = 0x30; - public static final int MODE_GPRS_SMS = 0x33; - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .expression("[A-Z]+") - .number("(dd)(dd)(dd)") // time (hhmmss) - .expression("([AV])") // validity - .number("(dd)(dd.dddd)([NS])") // latitude - .number("(ddd)(dd.dddd)([EW])") // longitude - .number("(ddd.ddd)") // speed - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .text(")") - .compile(); - - private void sendResponse(Channel channel, int type, ByteBuf dataSequence, ByteBuf content) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte('['); - response.writeByte(type); - response.writeBytes(dataSequence); - response.writeByte(content.readableBytes()); - response.writeBytes(content); - content.release(); - response.writeByte(']'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(1); // header - int type = buf.readUnsignedByte(); - ByteBuf dataSequence = buf.readSlice(10); - int length = buf.readUnsignedByte(); - - if (type == MSG_LOGIN_REQUEST || type == MSG_LOGIN_REQUEST_2) { - - ByteBuf data = buf.readSlice(length); - - String id; - if (type == MSG_LOGIN_REQUEST) { - id = data.toString(StandardCharsets.US_ASCII); - } else { - id = data.copy(1, 15).toString(StandardCharsets.US_ASCII); - } - - if (getDeviceSession(channel, remoteAddress, id) != null) { - ByteBuf response = Unpooled.buffer(); - response.writeByte(MODE_GPRS); - response.writeBytes(data); - sendResponse(channel, MSG_LOGIN_RESPONSE, dataSequence, response); - } - - } else if (type == MSG_HEARTBEAT_REQUEST) { - - sendResponse(channel, MSG_HEARTBEAT_RESPONSE, dataSequence, buf.readRetainedSlice(length)); - - } else { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); - if (!parser.matches()) { - 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)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Tk103FrameDecoder.java b/src/org/traccar/protocol/Tk103FrameDecoder.java deleted file mode 100644 index b61a42563..000000000 --- a/src/org/traccar/protocol/Tk103FrameDecoder.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2017 Valerii Vyshniak (val@val.one) - * 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. - * 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 Tk103FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 2) { - return null; - } - - int frameStartIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '('); - if (frameStartIndex == -1) { - buf.clear(); - return null; - } - - int frameEndIndex, freeTextSymbolCounter; - for (frameEndIndex = frameStartIndex, freeTextSymbolCounter = 0;; frameEndIndex++) { - int freeTextIndex = frameEndIndex; - frameEndIndex = buf.indexOf(frameEndIndex, buf.writerIndex(), (byte) ')'); - if (frameEndIndex == -1) { - break; - } - for (;; freeTextIndex++, freeTextSymbolCounter++) { - freeTextIndex = buf.indexOf(freeTextIndex, frameEndIndex, (byte) '$'); - if (freeTextIndex == -1 || freeTextIndex >= frameEndIndex) { - break; - } - } - if (freeTextSymbolCounter % 2 == 0) { - break; - } - } - - if (frameEndIndex == -1) { - while (buf.readableBytes() > 1024) { - int discardUntilIndex = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) '('); - if (discardUntilIndex == -1) { - buf.clear(); - } else { - buf.readerIndex(discardUntilIndex); - } - } - return null; - } - - buf.readerIndex(frameStartIndex); - - return buf.readRetainedSlice(frameEndIndex + 1 - frameStartIndex); - } - -} diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java deleted file mode 100644 index fa83133e2..000000000 --- a/src/org/traccar/protocol/Tk103Protocol.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 Christoph Krey (c@ckrey.de) - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class Tk103Protocol extends BaseProtocol { - - public Tk103Protocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_GET_DEVICE_STATUS, - Command.TYPE_IDENTIFICATION, - Command.TYPE_MODE_DEEP_SLEEP, - Command.TYPE_MODE_POWER_SAVING, - Command.TYPE_ALARM_SOS, - Command.TYPE_SET_CONNECTION, - Command.TYPE_SOS_NUMBER, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_POSITION_STOP, - Command.TYPE_GET_VERSION, - Command.TYPE_POWER_OFF, - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_SET_ODOMETER, - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME, - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Tk103FrameDecoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tk103ProtocolEncoder()); - pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tk103ProtocolEncoder()); - pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java deleted file mode 100644 index 9e28b5051..000000000 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * 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.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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class Tk103ProtocolDecoder extends BaseProtocolDecoder { - - private boolean decodeLow; - - public Tk103ProtocolDecoder(Protocol protocol) { - super(protocol); - decodeLow = Context.getConfig().getBoolean(getProtocolName() + ".decodeLow"); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(").optional() - .number("(d+)(,)?") // device id - .expression("(.{4}),?") // command - .number("(d*)") - .number("(dd)(dd)(dd),?") // date (mmddyy if comma-delimited, otherwise yyddmm) - .expression("([AV]),?") // validity - .number("(d+)(dd.d+)") // latitude - .expression("([NS]),?") - .number("(d+)(dd.d+)") // longitude - .expression("([EW]),?") - .number("(d+.d)(?:d*,)?") // speed - .number("(dd)(dd)(dd),?") // time (hhmmss) - .groupBegin() - .number("(?:([d.]{6})|(dd)),?") // course - .number("([01])") // charge - .number("([01])") // ignition - .number("(x)") // io - .number("(x)") // io - .number("(x)") // io - .number("(xxx)") // fuel - .number("L(x+)") // odometer - .or() - .number("(d+.d+)") // course - .groupEnd() - .any() - .number("([+-]ddd.d)?") // temperature - .text(")").optional() - .compile(); - - private static final Pattern PATTERN_BATTERY = new PatternBuilder() - .text("(").optional() - .number("(d+),") // device id - .text("ZC20,") - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d+),") // battery level - .number("(d+),") // battery voltage - .number("(d+),") // power voltage - .number("d+") // installed - .any() - .compile(); - - private static final Pattern PATTERN_NETWORK = new PatternBuilder() - .text("(").optional() - .number("(d{12})") // device id - .text("BZ00,") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),") // cid - .any() - .compile(); - - private static final Pattern PATTERN_LBSWIFI = new PatternBuilder() - .text("(").optional() - .number("(d+),") // device id - .expression("(.{4}),") // command - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(d+),") // lac - .number("(d+),") // cid - .number("(d+),") // number of wifi macs - .number("((?:(?:xx:){5}(?:xx)\\*[-+]?d+\\*d+,)*)") - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd)") // time (hhmmss) - .any() - .compile(); - - private static final Pattern PATTERN_COMMAND_RESULT = new PatternBuilder() - .text("(").optional() - .number("(d+),") // device id - .expression(".{4},") // command - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("\\$([\\s\\S]*?)(?:\\$|$)") // message - .any() - .compile(); - - private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_ACCIDENT; - case 2: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_VIBRATION; - case 4: - return Position.ALARM_LOW_SPEED; - case 5: - return Position.ALARM_OVERSPEED; - case 6: - return Position.ALARM_GEOFENCE_EXIT; - default: - return null; - } - } - - private void decodeType(Position position, String type, String data) { - switch (type) { - case "BO01": - position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0')); - break; - case "ZC11": - case "DW31": - case "DW51": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "ZC12": - case "DW32": - case "DW52": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "ZC13": - case "DW33": - case "DW53": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "ZC15": - case "DW35": - case "DW55": - position.set(Position.KEY_IGNITION, true); - break; - case "ZC16": - case "DW36": - case "DW56": - position.set(Position.KEY_IGNITION, false); - break; - case "ZC29": - case "DW42": - case "DW62": - position.set(Position.KEY_IGNITION, true); - break; - case "ZC17": - case "DW37": - case "DW57": - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - case "ZC25": - case "DW3E": - case "DW5E": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "ZC26": - case "DW3F": - case "DW5F": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - case "ZC27": - case "DW40": - case "DW60": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - default: - break; - } - } - - private Integer decodeBattery(int value) { - switch (value) { - case 6: - return 100; - case 5: - return 80; - case 4: - return 50; - case 3: - return 20; - case 2: - return 10; - default: - return null; - } - } - - private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_BATTERY, 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()); - - getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - int batterylevel = parser.nextInt(0); - if (batterylevel != 255) { - position.set(Position.KEY_BATTERY_LEVEL, decodeBattery(batterylevel)); - } - - int battery = parser.nextInt(0); - if (battery != 65535) { - position.set(Position.KEY_BATTERY, battery * 0.01); - } - - int power = parser.nextInt(0); - if (power != 65535) { - position.set(Position.KEY_POWER, power * 0.1); - } - - return position; - } - - private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_NETWORK, 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()); - - getLastLocation(position, null); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - - return position; - } - - private Position decodeLbsWifi(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_LBSWIFI, 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()); - - decodeType(position, parser.next(), "0"); - - getLastLocation(position, null); - - Network network = new Network(); - - network.addCellTower(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt())); - - int wifiCount = parser.nextInt(); - if (parser.hasNext()) { - String[] wifimacs = parser.next().split(","); - if (wifimacs.length == wifiCount) { - for (int i = 0; i < wifiCount; i++) { - String[] wifiinfo = wifimacs[i].split("\\*"); - network.addWifiAccessPoint(WifiAccessPoint.from( - wifiinfo[0], Integer.parseInt(wifiinfo[1]), Integer.parseInt(wifiinfo[2]))); - } - } - } - - if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { - position.setNetwork(network); - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - return position; - } - - private Position decodeCommandResult(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_COMMAND_RESULT, 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()); - - getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.set(Position.KEY_RESULT, parser.next()); - - return position; - - } - -@Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (channel != null) { - String id = sentence.substring(1, 13); - String type = sentence.substring(13, 17); - if (type.equals("BP00")) { - channel.writeAndFlush(new NetworkMessage("(" + id + "AP01HSO)", remoteAddress)); - return null; - } else if (type.equals("BP05")) { - channel.writeAndFlush(new NetworkMessage("(" + id + "AP05)", remoteAddress)); - } - } - - if (sentence.contains("ZC20")) { - return decodeBattery(channel, remoteAddress, sentence); - } else if (sentence.contains("BZ00")) { - return decodeNetwork(channel, remoteAddress, sentence); - } else if (sentence.contains("ZC03")) { - return decodeCommandResult(channel, remoteAddress, sentence); - } else if (sentence.contains("DW5")) { - return decodeLbsWifi(channel, remoteAddress, sentence); - } - - 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()); - - boolean alternative = parser.next() != null; - - decodeType(position, parser.next(), parser.next()); - - DateBuilder dateBuilder = new DateBuilder(); - if (alternative) { - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - } else { - dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - } - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.setSpeed(convertSpeed(parser.nextDouble(0), "kmh")); - - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - if (parser.hasNext()) { - position.setCourse(parser.nextDouble()); - } - if (parser.hasNext()) { - position.setCourse(parser.nextDouble()); - } - - if (parser.hasNext(7)) { - position.set(Position.KEY_CHARGE, parser.nextInt() == 0); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - - int mask1 = parser.nextHexInt(); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask1, 0) ? 1 : 0); - position.set("panic", BitUtil.check(mask1, 1) ? 1 : 0); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(mask1, 2) ? 1 : 0); - if (decodeLow || BitUtil.check(mask1, 3)) { - position.set(Position.KEY_BLOCKED, BitUtil.check(mask1, 3) ? 1 : 0); - } - - int mask2 = parser.nextHexInt(); - for (int i = 0; i < 3; i++) { - if (decodeLow || BitUtil.check(mask2, i)) { - position.set("hs" + (3 - i), BitUtil.check(mask2, i) ? 1 : 0); - } - } - if (decodeLow || BitUtil.check(mask2, 3)) { - position.set(Position.KEY_DOOR, BitUtil.check(mask2, 3) ? 1 : 0); - } - - int mask3 = parser.nextHexInt(); - for (int i = 1; i <= 3; i++) { - if (decodeLow || BitUtil.check(mask3, i)) { - position.set("ls" + (3 - i + 1), BitUtil.check(mask3, i) ? 1 : 0); - } - } - - position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); - position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); - } - - if (parser.hasNext()) { - position.setCourse(parser.nextDouble()); - } - - if (parser.hasNext()) { - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java deleted file mode 100644 index 98edc8cb5..000000000 --- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2017 Christoph Krey (c@ckrey.de) - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.protocol; - -import org.traccar.Context; -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class Tk103ProtocolEncoder extends StringProtocolEncoder { - - private final boolean forceAlternative; - - public Tk103ProtocolEncoder() { - this.forceAlternative = false; - } - - public Tk103ProtocolEncoder(boolean forceAlternative) { - this.forceAlternative = forceAlternative; - } - - private String formatAlt(Command command, String format, String... keys) { - return formatCommand(command, "[begin]sms2," + format + ",[end]", keys); - } - - @Override - protected Object encodeCommand(Command command) { - - boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "tk103.alternative", false, true); - - initDevicePassword(command, "123456"); - - 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_POWER_OFF: - return formatAlt(command, "*turnoff*"); - case Command.TYPE_REBOOT_DEVICE: - return formatAlt(command, "88888888"); - case Command.TYPE_POSITION_SINGLE: - return formatAlt(command, "*getposl*"); - case Command.TYPE_POSITION_PERIODIC: - return formatAlt(command, "*routetrack*99*"); - case Command.TYPE_POSITION_STOP: - return formatAlt(command, "*routetrackoff*"); - case Command.TYPE_GET_DEVICE_STATUS: - return formatAlt(command, "*status*"); - case Command.TYPE_IDENTIFICATION: - return formatAlt(command, "999999"); - case Command.TYPE_MODE_DEEP_SLEEP: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleep*2*" : "*sleepoff*"); - case Command.TYPE_MODE_POWER_SAVING: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleepv*" : "*sleepoff*"); - case Command.TYPE_ALARM_SOS: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*soson*" : "*sosoff*"); - case Command.TYPE_SET_CONNECTION: - return formatAlt(command, "*setip*%s*{%s}*", - command.getString(Command.KEY_SERVER).replace(".", "*"), Command.KEY_PORT); - case Command.TYPE_SOS_NUMBER: - return formatAlt(command, "*master*{%s}*{%s}*", Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE); - default: - return null; - } - } 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: - return formatCommand(command, "({%s}AT00)", Command.KEY_UNIQUE_ID); - case Command.TYPE_SET_ODOMETER: - return formatCommand(command, "({%s}AX01)", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "({%s}AP00)", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "({%s}AR00%s0000)", Command.KEY_UNIQUE_ID, - String.format("%04X", command.getInteger(Command.KEY_FREQUENCY))); - case Command.TYPE_POSITION_STOP: - return formatCommand(command, "({%s}AR0000000000)", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_STOP: - 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: - return null; - } - } - } - -} diff --git a/src/org/traccar/protocol/Tlt2hProtocol.java b/src/org/traccar/protocol/Tlt2hProtocol.java deleted file mode 100644 index 12fd92afa..000000000 --- a/src/org/traccar/protocol/Tlt2hProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Tlt2hProtocol extends BaseProtocol { - - public Tlt2hProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tlt2hProtocolDecoder(Tlt2hProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/org/traccar/protocol/Tlt2hProtocolDecoder.java deleted file mode 100644 index f67ff88db..000000000 --- a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { - - public Tlt2hProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_HEADER = new PatternBuilder() - .number("#(d+)#") // imei - .any() - .expression("([^#]+)#") // status - .number("d+") // number of records - .compile(); - - private static final Pattern PATTERN_POSITION = new PatternBuilder() - .number("#(x+)?") // cell info - .text("$GPRMC,") - .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d+)(dd.d+),") // longitude - .number("([EW]),") - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .any() - .compile(); - - private void decodeStatus(Position position, String status) { - switch (status) { - case "AUTOSTART": - case "AUTO": - position.set(Position.KEY_IGNITION, true); - break; - case "AUTOSTOP": - case "AUTOLOW": - position.set(Position.KEY_IGNITION, false); - break; - case "TOWED": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "SOS": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "DEF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BLP": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "CLP": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case "OS": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); - break; - case "RS": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); - break; - case "OVERSPEED": - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - default: - break; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - sentence = sentence.trim(); - - String header = sentence.substring(0, sentence.indexOf('\r')); - Parser parser = new Parser(PATTERN_HEADER, header); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - String status = parser.next(); - - String[] messages = sentence.substring(sentence.indexOf('\n') + 1).split("\r\n"); - List<Position> positions = new LinkedList<>(); - - for (String message : messages) { - parser = new Parser(PATTERN_POSITION, message); - if (parser.matches()) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - parser.next(); // base station info - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - decodeStatus(position, status); - - positions.add(position); - } - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/TlvProtocol.java b/src/org/traccar/protocol/TlvProtocol.java deleted file mode 100644 index 94f5da94f..000000000 --- a/src/org/traccar/protocol/TlvProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - * 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.CharacterDelimiterFrameDecoder; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class TlvProtocol extends BaseProtocol { - - public TlvProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); - pipeline.addLast(new TlvProtocolDecoder(TlvProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java deleted file mode 100644 index 36cf7859f..000000000 --- a/src/org/traccar/protocol/TlvProtocolDecoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; - -public class TlvProtocolDecoder extends BaseProtocolDecoder { - - public TlvProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, String... arguments) { - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeCharSequence(type, StandardCharsets.US_ASCII); - for (String argument : arguments) { - response.writeByte(argument.length()); - response.writeCharSequence(argument, StandardCharsets.US_ASCII); - } - response.writeByte(0); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - } - - 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 { - - ByteBuf buf = (ByteBuf) msg; - - String type = buf.readSlice(2).toString(StandardCharsets.US_ASCII); - - if (channel != null) { - switch (type) { - case "0A": - case "0C": - sendResponse(channel, remoteAddress, type); - break; - case "0B": - sendResponse(channel, remoteAddress, type, "1482202689", "10", "20", "15"); - break; - case "0E": - case "0F": - sendResponse(channel, remoteAddress, type, "30", "Unknown"); - break; - default: - break; - } - } - - if (type.equals("0E")) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readArgument(buf)); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - position.setTime(new Date(Long.parseLong(readArgument(buf)) * 1000)); - - readArgument(buf); // location identifier - - position.setLongitude(Double.parseDouble(readArgument(buf))); - position.setLatitude(Double.parseDouble(readArgument(buf))); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(readArgument(buf)))); - position.setCourse(Double.parseDouble(readArgument(buf))); - - position.set(Position.KEY_SATELLITES, Integer.parseInt(readArgument(buf))); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TmgFrameDecoder.java b/src/org/traccar/protocol/TmgFrameDecoder.java deleted file mode 100644 index 205adaa51..000000000 --- a/src/org/traccar/protocol/TmgFrameDecoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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'; - } - - 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))) { - 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) { - - buf.readerIndex(beginIndex); - - int endIndex = buf.indexOf(beginIndex, buf.writerIndex(), (byte) '\n'); - - if (endIndex >= 0) { - ByteBuf frame = buf.readRetainedSlice(endIndex - beginIndex); - buf.readByte(); // delimiter - return frame; - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TmgProtocol.java b/src/org/traccar/protocol/TmgProtocol.java deleted file mode 100644 index 020332ce7..000000000 --- a/src/org/traccar/protocol/TmgProtocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; - -public class TmgProtocol extends BaseProtocol { - - public TmgProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TmgFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TmgProtocolDecoder(TmgProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java deleted file mode 100644 index d27849f8c..000000000 --- a/src/org/traccar/protocol/TmgProtocolDecoder.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.regex.Pattern; - -public class TmgProtocolDecoder extends BaseProtocolDecoder { - - public TmgProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$") - .expression("(...),") // type - .expression("[LH],").optional() // history - .number("(d+),") // imei - .number("(dd)(dd)(dddd),") // date (ddmmyyyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(d),") // status - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(ddd)(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .groupBegin() - .number("(-?d+.?d*),") // altitude - .number("(d+.d+),") // hdop - .number("(d+),") // satellites - .number("(d+),") // visible satellites - .number("([^,]*),") // operator - .number("(d+),") // rssi - .number("[^,]*,") // cid - .expression("([01]),") // ignition - .number("(d+.?d*),") // battery - .number("(d+.?d*),") // power - .expression("([01]+),") // input - .expression("([01]+),") // output - .expression("[01]+,") // temper status - .number("(d+.?d*)[^,]*,") // adc1 - .number("(d+.?d*)[^,]*,") // adc2 - .number("d+.?d*,") // trip meter - .expression("([^,]*),") // software version - .expression("([^,]*),").optional() // rfid - .or() - .number("[^,]*,") // cid - .number("(d+),") // rssi - .number("(d+),") // satellites - .number("[^,]*,") // battery level - .expression("([01]),") // ignition - .expression("([LH]{4}),") // input - .expression("[NT]{4},") // tamper status - .expression("([LH]{2}),") // output - .number("(d+.d+),") // adc1 - .number("(d+.d+),") // adc1 - .number("[^,]*,") // device id - .number("(d+),") // odometer - .groupEnd() - .any() - .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; - } - - String type = parser.next(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - switch (type) { - case "rmv": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "ebl": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case "ibl": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "tmp": - case "smt": - case "btt": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - case "ion": - position.set(Position.KEY_IGNITION, true); - break; - case "iof": - position.set(Position.KEY_IGNITION, false); - break; - default: - break; - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.nextInt() > 0); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - if (parser.hasNext(15)) { - - position.setAltitude(parser.nextDouble()); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt()); - position.set(Position.KEY_OPERATOR, parser.next()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - position.set(Position.KEY_POWER, parser.nextDouble()); - - int input = parser.nextBinInt(); - int output = parser.nextBinInt(); - - if (!BitUtil.check(input, 0)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); - position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - } - - if (parser.hasNext(6)) { - - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - - char[] input = parser.next().toCharArray(); - for (int i = 0; i < input.length; i++) { - position.set(Position.PREFIX_IN + (i + 1), input[i] == 'H'); - } - - char[] output = parser.next().toCharArray(); - for (int i = 0; i < output.length; i++) { - position.set(Position.PREFIX_OUT + (i + 1), output[i] == 'H'); - } - - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextInt()); - - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/TopflytechProtocol.java b/src/org/traccar/protocol/TopflytechProtocol.java deleted file mode 100644 index 303072bdb..000000000 --- a/src/org/traccar/protocol/TopflytechProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class TopflytechProtocol extends BaseProtocol { - - public TopflytechProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new TopflytechProtocolDecoder(TopflytechProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/org/traccar/protocol/TopflytechProtocolDecoder.java deleted file mode 100644 index 6de053c32..000000000 --- a/src/org/traccar/protocol/TopflytechProtocolDecoder.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class TopflytechProtocolDecoder extends BaseProtocolDecoder { - - public TopflytechProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .number("(d+)") // imei - .any() - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .expression("([AV])") - .number("(dd)(dd.dddd)([NS])") // latitude - .number("(ddd)(dd.dddd)([EW])") // longitude - .number("(ddd.d)") // speed - .number("(d+.d+)") // course - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - return position; - } - -} diff --git a/src/org/traccar/protocol/TotemFrameDecoder.java b/src/org/traccar/protocol/TotemFrameDecoder.java deleted file mode 100644 index 3fa5abc7a..000000000 --- a/src/org/traccar/protocol/TotemFrameDecoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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 java.nio.charset.StandardCharsets; - -import org.traccar.BaseFrameDecoder; -import org.traccar.helper.BufferUtil; - -public class TotemFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 10) { - return null; - } - - int beginIndex = BufferUtil.indexOf("$$", buf); - if (beginIndex == -1) { - return null; - } else if (beginIndex > buf.readerIndex()) { - buf.readerIndex(beginIndex); - } - - int length; - - if (buf.getByte(buf.readerIndex() + 2) == (byte) '0') { - length = Integer.parseInt(buf.toString(buf.readerIndex() + 2, 4, StandardCharsets.US_ASCII)); - } else { - length = Integer.parseInt(buf.toString(buf.readerIndex() + 2, 2, StandardCharsets.US_ASCII), 16); - } - - if (length <= buf.readableBytes()) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TotemProtocol.java b/src/org/traccar/protocol/TotemProtocol.java deleted file mode 100644 index 66e1ec4f1..000000000 --- a/src/org/traccar/protocol/TotemProtocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -public class TotemProtocol extends BaseProtocol { - - public TotemProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_RESUME, - Command.TYPE_ENGINE_STOP - ); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TotemFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TotemProtocolEncoder()); - pipeline.addLast(new TotemProtocolDecoder(TotemProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java deleted file mode 100644 index cd7f684b8..000000000 --- a/src/org/traccar/protocol/TotemProtocolDecoder.java +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright 2013 - 2019 Anton Tananaev (anton@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.Protocol; -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; -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 TotemProtocolDecoder extends BaseProtocolDecoder { - - public TotemProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN1 = new PatternBuilder() - .text("$$") // header - .number("xx") // length - .number("(d+)|") // imei - .expression("(..)") // alarm - .text("$GPRMC,") - .number("(dd)(dd)(dd).d+,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d+)(dd.d+),([NS]),") // latitude - .number("(d+)(dd.d+),([EW]),") // longitude - .number("(d+.?d*)?,") // speed - .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .expression("[^*]*").text("*") - .number("xx|") // checksum - .number("(d+.d+)|") // pdop - .number("(d+.d+)|") // hdop - .number("(d+.d+)|") // vdop - .number("(d+)|") // io status - .number("d+|") // battery time - .number("d") // charged - .number("(ddd)") // battery - .number("(dddd)|") // power - .number("(d+)|").optional() // adc - .number("x*(xxxx)") // lac - .number("(xxxx)|") // cid - .number("(d+)|") // temperature - .number("(d+.d+)|") // odometer - .number("d+|") // serial number - .any() - .number("xxxx") // checksum - .any() - .compile(); - - private static final Pattern PATTERN2 = new PatternBuilder() - .text("$$") // header - .number("xx") // length - .number("(d+)|") // imei - .expression("(..)") // alarm type - .number("(dd)(dd)(dd)") // date (ddmmyy) - .number("(dd)(dd)(dd)|") // time (hhmmss) - .expression("([AV])|") // validity - .number("(d+)(dd.d+)|") // latitude - .expression("([NS])|") - .number("(d+)(dd.d+)|") // longitude - .expression("([EW])|") - .number("(d+.d+)?|") // speed - .number("(d+)?|") // course - .number("(d+.d+)|") // hdop - .number("(d+)|") // io status - .number("d") // charged - .number("(dd)") // battery - .number("(dd)|") // external power - .number("(d+)|") // adc - .number("(xxxx)") // lac - .number("(xxxx)|") // cid - .number("(d+)|") // temperature - .number("(d+.d+)|") // odometer - .number("d+|") // serial number - .number("xxxx") // checksum - .any() - .compile(); - - private static final Pattern PATTERN3 = new PatternBuilder() - .text("$$") // header - .number("xx") // length - .number("(d+)|") // imei - .expression("(..)") // alarm type - .number("(dd)(dd)(dd)") // date (ddmmyy) - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(xxxx)") // io status - .expression("[01]") // charging - .number("(dd)") // battery - .number("(dd)") // external power - .number("(dddd)") // adc 1 - .number("(dddd)") // adc 2 - .number("(ddd)") // temperature 1 - .number("(ddd)") // temperature 2 - .number("(xxxx)") // lac - .number("(xxxx)") // cid - .expression("([AV])") // validity - .number("(dd)") // satellites - .number("(ddd)") // course - .number("(ddd)") // speed - .number("(dd.d)") // pdop - .number("(d{7})") // odometer - .number("(dd)(dd.dddd)([NS])") // latitude - .number("(ddd)(dd.dddd)([EW])") // longitude - .number("dddd") // serial number - .number("xxxx") // checksum - .any() - .compile(); - - private static final Pattern PATTERN4 = new PatternBuilder() - .text("$$") // header - .number("dddd") // length - .number("(xx)") // type - .number("(d+)|") // imei - .number("(x{8})") // status - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(dd)") // battery - .number("(dd)") // external power - .number("(dddd)") // adc 1 - .groupBegin() - .groupBegin() - .number("(dddd)") // adc 2 - .number("(dddd)") // adc 3 - .number("(dddd)") // adc 4 - .groupEnd("?") - .number("(dddd)") // temperature 1 - .number("(dddd)?") // temperature 2 - .groupEnd("?") - .number("(xxxx)") // lac - .number("(xxxx)") // cid - .groupBegin() - .number("(dd)") // mcc - .number("(ddd)") // mnc - .groupEnd("?") - .number("(dd)") // satellites - .number("(dd)") // gsm (rssi) - .number("(ddd)") // course - .number("(ddd)") // speed - .number("(dd.d)") // hdop - .number("(d{7})") // odometer - .number("(dd)(dd.dddd)([NS])") // latitude - .number("(ddd)(dd.dddd)([EW])") // longitude - .number("dddd") // serial number - .number("xx") // checksum - .any() - .compile(); - - private String decodeAlarm123(int value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x30: - return Position.ALARM_PARKING; - case 0x42: - return Position.ALARM_GEOFENCE_EXIT; - case 0x43: - return Position.ALARM_GEOFENCE_ENTER; - default: - return null; - } - } - - private String decodeAlarm4(int value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x02: - return Position.ALARM_OVERSPEED; - case 0x04: - return Position.ALARM_GEOFENCE_EXIT; - case 0x05: - return Position.ALARM_GEOFENCE_ENTER; - case 0x40: - return Position.ALARM_SHOCK; - case 0x42: - return Position.ALARM_ACCELERATION; - case 0x43: - return Position.ALARM_BRAKING; - default: - return null; - } - } - - private boolean decode12(Position position, Parser parser, Pattern pattern) { - - if (parser.hasNext()) { - position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16))); - } - DateBuilder dateBuilder = new DateBuilder(); - int year = 0, month = 0, day = 0; - if (pattern == PATTERN2) { - day = parser.nextInt(0); - month = parser.nextInt(0); - year = parser.nextInt(0); - } - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - if (pattern == PATTERN1) { - day = parser.nextInt(0); - month = parser.nextInt(0); - year = parser.nextInt(0); - } - if (year == 0) { - return false; // ignore invalid data - } - dateBuilder.setDate(year, month, day); - position.setTime(dateBuilder.getDate()); - - if (pattern == PATTERN1) { - position.set(Position.KEY_PDOP, parser.nextDouble()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_VDOP, parser.nextDouble()); - } else { - position.set(Position.KEY_HDOP, parser.nextDouble()); - } - - 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()); - - int lac = parser.nextHexInt(0); - int cid = parser.nextHexInt(0); - if (lac != 0 && cid != 0) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); - } - - position.set(Position.PREFIX_TEMP + 1, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - return true; - } - - private boolean decode3(Position position, Parser parser) { - - if (parser.hasNext()) { - position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16))); - } - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.set(Position.PREFIX_IO + 1, parser.next()); - 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()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.PREFIX_TEMP + 1, parser.next()); - position.set(Position.PREFIX_TEMP + 2, parser.next()); - - position.setNetwork(new Network( - CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); - - position.setValid(parser.next().equals("A")); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setCourse(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - position.set(Position.KEY_PDOP, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0) * 1000); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - return true; - } - - private boolean decode4(Position position, Parser parser) { - - long status = parser.nextHexLong(); - - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 1) ? Position.ALARM_SOS : null); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 32 - 2)); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 3) ? Position.ALARM_OVERSPEED : null); - position.set(Position.KEY_CHARGE, BitUtil.check(status, 32 - 4)); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 5) ? Position.ALARM_GEOFENCE_EXIT : null); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 6) ? Position.ALARM_GEOFENCE_ENTER : null); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 32 - 9)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 32 - 10)); - position.set(Position.PREFIX_OUT + 3, BitUtil.check(status, 32 - 11)); - position.set(Position.PREFIX_OUT + 4, BitUtil.check(status, 32 - 12)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(status, 32 - 13)); - position.set(Position.PREFIX_IN + 3, BitUtil.check(status, 32 - 14)); - position.set(Position.PREFIX_IN + 4, BitUtil.check(status, 32 - 15)); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 16) ? Position.ALARM_SHOCK : null); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 18) ? Position.ALARM_LOW_BATTERY : null); - position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 22) ? Position.ALARM_JAMMING : null); - - - position.setTime(parser.nextDateTime()); - - position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); - position.set(Position.KEY_POWER, parser.nextDouble()); - - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.PREFIX_ADC + 3, parser.next()); - position.set(Position.PREFIX_ADC + 4, parser.next()); - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - if (parser.hasNext()) { - position.set(Position.PREFIX_TEMP + 2, parser.next()); - position.setValid(BitUtil.check(status, 32 - 20)); - } else { - position.setValid(BitUtil.check(status, 32 - 18)); - } - - int lac = parser.nextHexInt(); - int cid = parser.nextHexInt(); - CellTower cellTower; - if (parser.hasNext(2)) { - int mnc = parser.nextInt(); - int mcc = parser.nextInt(); - cellTower = CellTower.from(mcc, mnc, lac, cid); - } else { - cellTower = CellTower.fromLacCid(lac, cid); - } - position.set(Position.KEY_SATELLITES, parser.nextInt()); - cellTower.setSignalStrength(parser.nextInt()); - position.setNetwork(new Network(cellTower)); - - position.setCourse(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextInt() * 1000); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - return true; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - Pattern pattern = PATTERN3; - if (sentence.charAt(2) == '0') { - pattern = PATTERN4; - } else if (sentence.contains("$GPRMC")) { - pattern = PATTERN1; - } else { - int index = sentence.indexOf('|'); - if (index != -1 && sentence.indexOf('|', index + 1) != -1) { - pattern = PATTERN2; - } - } - - Parser parser = new Parser(pattern, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - if (pattern == PATTERN4) { - position.set(Position.KEY_ALARM, decodeAlarm4(parser.nextHexInt())); - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - boolean result; - if (pattern == PATTERN1 || pattern == PATTERN2) { - result = decode12(position, parser, pattern); - } else if (pattern == PATTERN3) { - result = decode3(position, parser); - } else { - result = decode4(position, parser); - } - - if (channel != null) { - if (pattern == PATTERN4) { - 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.writeAndFlush(new NetworkMessage("ACK OK\r\n", remoteAddress)); - } - } - - return result ? position : null; - } - -} diff --git a/src/org/traccar/protocol/TotemProtocolEncoder.java b/src/org/traccar/protocol/TotemProtocolEncoder.java deleted file mode 100644 index b5049859d..000000000 --- a/src/org/traccar/protocol/TotemProtocolEncoder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2015 Irving Gonzalez - * Copyright 2015 - 2016 Anton Tananaev (anton@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.model.Command; - -public class TotemProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, "000000"); - - switch (command.getType()) { - // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "*{%s},025,C,1#", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "*{%s},025,C,0#", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Tr20Protocol.java b/src/org/traccar/protocol/Tr20Protocol.java deleted file mode 100644 index 3eee9d9c3..000000000 --- a/src/org/traccar/protocol/Tr20Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Tr20Protocol extends BaseProtocol { - - public Tr20Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/org/traccar/protocol/Tr20ProtocolDecoder.java deleted file mode 100644 index c2e6c381f..000000000 --- a/src/org/traccar/protocol/Tr20ProtocolDecoder.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -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 Tr20ProtocolDecoder extends BaseProtocolDecoder { - - public Tr20ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_PING = new PatternBuilder() - .text("%%") - .expression("[^,]+,") - .number("(d+)") - .compile(); - - private static final Pattern PATTERN_DATA = new PatternBuilder() - .text("%%") - .expression("([^,]+),") // id - .expression("([AL]),") // validity - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([NS])") - .number("(dd)(dd.d+)") // latitude - .expression("([EW])") - .number("(ddd)(dd.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(?:NA|[FC]?(-?d+)),") // temperature - .number("(x{8}),") // status - .number("(d+)") // event - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN_PING, (String) msg); - if (parser.matches()) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - "&&" + parser.next() + "\r\n", remoteAddress)); // keep-alive response - } - return null; - } - - parser = new Parser(PATTERN_DATA, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.next().equals("A")); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.KEY_STATUS, parser.nextHexLong()); - position.set(Position.KEY_EVENT, parser.nextInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Tr900Protocol.java b/src/org/traccar/protocol/Tr900Protocol.java deleted file mode 100644 index b70521b35..000000000 --- a/src/org/traccar/protocol/Tr900Protocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -public class Tr900Protocol extends BaseProtocol { - - public Tr900Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/org/traccar/protocol/Tr900ProtocolDecoder.java deleted file mode 100644 index 319194c21..000000000 --- a/src/org/traccar/protocol/Tr900ProtocolDecoder.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class Tr900ProtocolDecoder extends BaseProtocolDecoder { - - public Tr900ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number(">(d+),") // id - .number("d+,") // period - .number("(d),") // fix - .number("(dd)(dd)(dd),") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([EW])") - .number("(ddd)(dd.d+),") // longitude - .expression("([NS])") - .number("(dd)(dd.d+),") // latitude - .expression("[^,]*,") // command - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+),") // gsm - .number("(d+),") // event - .number("(d+)-") // adc - .number("(d+),") // battery - .number("d+,") // impulses - .number("(d+),") // input - .number("(d+)") // status - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.nextInt(0) == 1); - - position.setTime(parser.nextDateTime()); - - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_RSSI, parser.nextDouble()); - position.set(Position.KEY_EVENT, parser.nextInt(0)); - position.set(Position.PREFIX_ADC + 1, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_STATUS, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/TrackboxProtocol.java b/src/org/traccar/protocol/TrackboxProtocol.java deleted file mode 100644 index 5da5abd64..000000000 --- a/src/org/traccar/protocol/TrackboxProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class TrackboxProtocol extends BaseProtocol { - - public TrackboxProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TrackboxProtocolDecoder(TrackboxProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/org/traccar/protocol/TrackboxProtocolDecoder.java deleted file mode 100644 index db8022738..000000000 --- a/src/org/traccar/protocol/TrackboxProtocolDecoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.util.regex.Pattern; - -public class TrackboxProtocolDecoder extends BaseProtocolDecoder { - - public TrackboxProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(dd)(dd)(dd).(ddd),") // time (hhmmss.sss) - .number("(dd)(dd.dddd)([NS]),") // latitude - .number("(ddd)(dd.dddd)([EW]),") // longitude - .number("(d+.d),") // hdop - .number("(-?d+.?d*),") // altitude - .number("(d),") // fix type - .number("(d+.d+),") // course - .number("d+.d+,") // speed (kph) - .number("(d+.d+),") // speed (knots) - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(d+)") // satellites - .compile(); - - private void sendResponse(Channel channel, SocketAddress remoteAddress) { - if (channel != null) { - channel.writeAndFlush(new NetworkMessage("=OK=\r\n", remoteAddress)); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("a=connect")) { - String id = sentence.substring(sentence.indexOf("i=") + 2); - if (getDeviceSession(channel, remoteAddress, id) != null) { - sendResponse(channel, remoteAddress); - } - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - sendResponse(channel, remoteAddress); - - 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)); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.set(Position.KEY_HDOP, parser.nextDouble()); - - position.setAltitude(parser.nextDouble(0)); - - int fix = parser.nextInt(0); - position.set(Position.KEY_GPS, fix); - position.setValid(fix > 0); - - position.setCourse(parser.nextDouble(0)); - position.setSpeed(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/TrakMateProtocol.java b/src/org/traccar/protocol/TrakMateProtocol.java deleted file mode 100644 index bda5df10f..000000000 --- a/src/org/traccar/protocol/TrakMateProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class TrakMateProtocol extends BaseProtocol { - - public TrakMateProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TrakMateProtocolDecoder(TrakMateProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/org/traccar/protocol/TrakMateProtocolDecoder.java deleted file mode 100644 index 4d5cb18f5..000000000 --- a/src/org/traccar/protocol/TrakMateProtocolDecoder.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class TrakMateProtocolDecoder extends BaseProtocolDecoder { - - public TrakMateProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_SRT = new PatternBuilder() - .text("^TMSRT|") - .expression("([^ ]+)|") // uid - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time (hhmmss) - .number("(dd)(dd)(dd)|") // date (ddmmyy) - .number("(d+.d+)|") // software ver - .number("(d+.d+)|") // Hardware ver - .any() - .compile(); - - private static final Pattern PATTERN_PER = new PatternBuilder() - .text("^TM") - .expression("...|") // type - .expression("([^ ]+)|") // uid - .number("(d+)|") // seq - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time (hhmmss) - .number("(dd)(dd)(dd)|") // date (ddmmyy) - .number("(d+.d+)|") // speed - .number("(d+.d+)|") // heading - .number("(d+)|").optional() // satellites - .number("([01])|") // ignition - .groupBegin() - .number("(d+)|") // dop1 - .number("(d+)|") // dop2 - .number("(d+.d+)|") // analog - .number("(d+.d+)|") // internal battery - .or() - .number("-?d+ -?d+ -?d+|") // accelerometer - .number("([01])|") // movement - .groupEnd() - .number("(d+.d+)|") // vehicle battery - .number("(d+.d+)|") // gps odometer - .number("(d+.d+)|").optional() // pulse odometer - .number("([01])|") // main power status - .number("([01])|") // gps data validity - .number("([01])|") // live or cache - .any() - .compile(); - - private static final Pattern PATTERN_ALT = new PatternBuilder() - .text("^TMALT|") - .expression("([^ ]+)|") // uid - .number("(d+)|") // seq - .number("(d+)|") // Alert type - .number("(d+)|") // Alert status - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time (hhmmss) - .number("(dd)(dd)(dd)|") // date (ddmmyy) - .number("(d+.d+)|") // speed - .number("(d+.d+)|") // heading - .any() - .compile(); - - private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_GEOFENCE; - case 4: - return Position.ALARM_POWER_CUT; - default: - return null; - } - } - - private Object decodeSrt(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_SRT, 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()); - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_VERSION_HW, parser.next()); - - return position; - } - - private Object decodeAlt(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_ALT, 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()); - - parser.next(); // seq - position.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt())); - parser.next(); // alert status or data - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - return position; - } - - private Object decodePer(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN_PER, (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()); - - parser.next(); // seq - - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); - - if (parser.hasNext(4)) { - position.set("dop1", parser.nextInt()); - position.set("dop2", parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - } - - if (parser.hasNext()) { - position.set(Position.KEY_MOTION, parser.nextInt(0) > 0); - } - - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_ODOMETER, parser.nextDouble()); - position.set("pulseOdometer", parser.nextDouble()); - position.set(Position.KEY_STATUS, parser.nextInt()); - - position.setValid(parser.nextInt() > 0); - - position.set(Position.KEY_ARCHIVE, parser.nextInt() > 0); - - return position; - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - int typeIndex = sentence.indexOf("^TM"); - if (typeIndex < 0) { - return null; - } - - String type = sentence.substring(typeIndex + 3, typeIndex + 6); - switch (type) { - case "ALT": - return decodeAlt(channel, remoteAddress, sentence); - case "SRT": - return decodeSrt(channel, remoteAddress, sentence); - default: - return decodePer(channel, remoteAddress, sentence); - } - } - -} diff --git a/src/org/traccar/protocol/TramigoFrameDecoder.java b/src/org/traccar/protocol/TramigoFrameDecoder.java deleted file mode 100644 index aaaaccb60..000000000 --- a/src/org/traccar/protocol/TramigoFrameDecoder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - * 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 TramigoFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 20) { - return null; - } - - int length; - if (buf.getUnsignedByte(buf.readerIndex()) == 0x80) { - length = buf.getUnsignedShortLE(buf.readerIndex() + 6); - } else { - length = buf.getUnsignedShort(buf.readerIndex() + 6); - } - - if (length >= buf.readableBytes()) { - return buf.readRetainedSlice(length); - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TramigoProtocol.java b/src/org/traccar/protocol/TramigoProtocol.java deleted file mode 100644 index f683ccc5d..000000000 --- a/src/org/traccar/protocol/TramigoProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class TramigoProtocol extends BaseProtocol { - - public TramigoProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TramigoFrameDecoder()); - pipeline.addLast(new TramigoProtocolDecoder(TramigoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TramigoProtocolDecoder.java b/src/org/traccar/protocol/TramigoProtocolDecoder.java deleted file mode 100644 index e42e2f670..000000000 --- a/src/org/traccar/protocol/TramigoProtocolDecoder.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.DateUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class TramigoProtocolDecoder extends BaseProtocolDecoder { - - public TramigoProtocolDecoder(Protocol protocol) { - super(protocol); - } - - public static final int MSG_COMPACT = 0x0100; - public static final int MSG_FULL = 0x00FE; - - private static final String[] DIRECTIONS = new String[] {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}; - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - int protocol = buf.readUnsignedByte(); - boolean legacy = protocol == 0x80; - - buf.readUnsignedByte(); // version id - 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 = legacy ? buf.readUnsignedInt() : buf.readUnsignedIntLE(); - buf.readUnsignedInt(); // time - - Position position = new Position(getProtocolName()); - position.set(Position.KEY_INDEX, index); - position.setValid(true); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - if (protocol == 0x01 && (type == MSG_COMPACT || type == MSG_FULL)) { - - // need to send ack? - - buf.readUnsignedShortLE(); // report trigger - buf.readUnsignedShortLE(); // state flag - - position.setLatitude(buf.readUnsignedIntLE() * 0.0000001); - position.setLongitude(buf.readUnsignedIntLE() * 0.0000001); - - 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.readUnsignedShortLE() * 0.194384); - position.setCourse(buf.readUnsignedShortLE()); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE()); - - position.set(Position.KEY_CHARGE, buf.readUnsignedShortLE()); - - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - - // parse other data - - return position; - - } else if (legacy) { - - if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Unpooled.copiedBuffer("gprs,ack," + index, StandardCharsets.US_ASCII), remoteAddress)); - } - - String sentence = buf.toString(StandardCharsets.US_ASCII); - - Pattern pattern = Pattern.compile("(-?\\d+\\.\\d+), (-?\\d+\\.\\d+)"); - Matcher matcher = pattern.matcher(sentence); - if (!matcher.find()) { - return null; - } - position.setLatitude(Double.parseDouble(matcher.group(1))); - position.setLongitude(Double.parseDouble(matcher.group(2))); - - pattern = Pattern.compile("([NSWE]{1,2}) with speed (\\d+) km/h"); - matcher = pattern.matcher(sentence); - if (matcher.find()) { - for (int i = 0; i < DIRECTIONS.length; i++) { - if (matcher.group(1).equals(DIRECTIONS[i])) { - position.setCourse(i * 45.0); - break; - } - } - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(matcher.group(2)))); - } - - pattern = Pattern.compile("(\\d{1,2}:\\d{2}(:\\d{2})? \\w{3} \\d{1,2})"); - matcher = pattern.matcher(sentence); - if (!matcher.find()) { - return null; - } - DateFormat dateFormat = new SimpleDateFormat( - matcher.group(2) != null ? "HH:mm:ss MMM d yyyy" : "HH:mm MMM d yyyy", Locale.ENGLISH); - position.setTime(DateUtil.correctYear( - dateFormat.parse(matcher.group(1) + " " + Calendar.getInstance().get(Calendar.YEAR)))); - - if (sentence.contains("Ignition on detected")) { - position.set(Position.KEY_IGNITION, true); - } else if (sentence.contains("Ignition off detected")) { - position.set(Position.KEY_IGNITION, false); - } - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/TrvProtocol.java b/src/org/traccar/protocol/TrvProtocol.java deleted file mode 100644 index 99a164cf1..000000000 --- a/src/org/traccar/protocol/TrvProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class TrvProtocol extends BaseProtocol { - - public TrvProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TrvProtocolDecoder(TrvProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java deleted file mode 100644 index b63385187..000000000 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.regex.Pattern; - -public class TrvProtocolDecoder extends BaseProtocolDecoder { - - public TrvProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("[A-Z]{2,3}") - .number("APdd") - .number("(dd)(dd)(dd)") // date (yymmdd) - .expression("([AV])") // validity - .number("(dd)(dd.d+)") // latitude - .expression("([NS])") - .number("(ddd)(dd.d+)") // longitude - .expression("([EW])") - .number("(ddd.d)") // speed - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("([d.]{6})") // course - .number("(ddd)") // gsm - .number("(ddd)") // satellites - .number("(ddd)") // battery - .number("(d)") // acc - .number("(dd)") // arm status - .number("(dd),") // working mode - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(d+),") // lac - .number("(d+)") // cell - .any() - .compile(); - - private static final Pattern PATTERN_HEATRBEAT = new PatternBuilder() - .expression("[A-Z]{2,3}") - .text("CP01,") - .number("(ddd)") // gsm - .number("(ddd)") // gps - .number("(ddd)") // battery - .number("(d)") // acc - .number("(dd)") // arm status - .number("(dd)") // working mode - .groupBegin() - .number("(ddd)") // interval - .number("d") // vibration alarm - .number("ddd") // vibration sensitivity - .number("d") // automatic arm - .number("dddd") // automatic arm time - .number("(d)") // blocked - .number("(d)") // power status - .number("(d)") // movement status - .groupEnd("?") - .any() - .compile(); - - private static final Pattern PATTERN_LBS = new PatternBuilder() - .expression("[A-Z]{2,3}") - .text("AP02,") - .expression("[^,]+,") // language - .number("[01],") // reply - .number("d+,") // cell count - .number("(d+),") // mcc - .number("(d+),") // mnc - .expression("(") - .groupBegin() - .number("d+|") // lac - .number("d+|") // cid - .number("d+,") // rssi - .groupEnd("+") - .expression(")") - .number("d+,") // wifi count - .expression("(.*)") // wifi - .compile(); - - private Boolean decodeOptionalValue(Parser parser, int activeValue) { - int value = parser.nextInt(); - if (value != 0) { - return value == activeValue; - } - return null; - } - - private void decodeCommon(Position position, Parser parser) { - - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_BATTERY, parser.nextInt()); - position.set(Position.KEY_IGNITION, decodeOptionalValue(parser, 1)); - position.set(Position.KEY_ARMED, decodeOptionalValue(parser, 1)); - - int mode = parser.nextInt(); - if (mode != 0) { - position.set("mode", mode); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - String id = sentence.startsWith("TRV") ? sentence.substring(0, 3) : sentence.substring(0, 2); - String type = sentence.substring(id.length(), id.length() + 4); - - if (channel != null) { - 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.writeAndFlush(new NetworkMessage(responseHeader + "," + time + ",0#", remoteAddress)); - } else if (type.equals("AP14")) { - channel.writeAndFlush(new NetworkMessage(responseHeader + ",0.000,0.000#", remoteAddress)); - } else { - channel.writeAndFlush(new NetworkMessage(responseHeader + "#", remoteAddress)); - } - } - - if (type.equals("AP00")) { - getDeviceSession(channel, remoteAddress, sentence.substring(id.length() + type.length())); - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - if (type.equals("CP01")) { - - Parser parser = new Parser(PATTERN_HEATRBEAT, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - decodeCommon(position, parser); - - if (parser.hasNext(3)) { - position.set(Position.KEY_BLOCKED, decodeOptionalValue(parser, 2)); - position.set(Position.KEY_CHARGE, decodeOptionalValue(parser, 1)); - position.set(Position.KEY_MOTION, decodeOptionalValue(parser, 1)); - } - - return position; - - } else if (type.equals("AP01") || type.equals("AP10")) { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - dateBuilder.setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - position.setCourse(parser.nextDouble()); - - decodeCommon(position, parser); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()))); - - return position; - - } else if (type.equals("AP02")) { - - Parser parser = new Parser(PATTERN_LBS, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - - Network network = new Network(); - - for (String cell : parser.next().split(",")) { - if (!cell.isEmpty()) { - String[] values = cell.split("\\|"); - network.addCellTower(CellTower.from( - mcc, mnc, - Integer.parseInt(values[0]), - Integer.parseInt(values[1]), - Integer.parseInt(values[2]))); - } - } - - for (String wifi : parser.next().split("&")) { - if (!wifi.isEmpty()) { - String[] values = wifi.split("\\|"); - network.addWifiAccessPoint(WifiAccessPoint.from(values[1], Integer.parseInt(values[2]))); - } - } - - position.setNetwork(network); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Tt8850Protocol.java b/src/org/traccar/protocol/Tt8850Protocol.java deleted file mode 100644 index 66a13da9e..000000000 --- a/src/org/traccar/protocol/Tt8850Protocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class Tt8850Protocol extends BaseProtocol { - - public Tt8850Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tt8850ProtocolDecoder(Tt8850Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java deleted file mode 100644 index 1010528c4..000000000 --- a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 Tt8850ProtocolDecoder extends BaseProtocolDecoder { - - public Tt8850ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .binary("0004,") - .number("xxxx,") - .expression("[01],") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .expression("([^,]+),") // imei - .any() - .number("(d{1,2})?,") // gps accuracy - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6}),") // longitude - .number("(-?d{1,2}.d{6}),") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(0ddd)?,") // mcc - .number("(0ddd)?,") // mnc - .number("(xxxx)?,") // lac - .number("(xxxx)?,") // cell - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(true); - position.setAccuracy(parser.nextInt(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - - position.setTime(parser.nextDateTime()); - - if (parser.hasNext(4)) { - position.setNetwork(new Network( - CellTower.from(parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/TytanProtocol.java b/src/org/traccar/protocol/TytanProtocol.java deleted file mode 100644 index 32e9acae1..000000000 --- a/src/org/traccar/protocol/TytanProtocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * 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; - -public class TytanProtocol extends BaseProtocol { - - public TytanProtocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java deleted file mode 100644 index 93d3a63d2..000000000 --- a/src/org/traccar/protocol/TytanProtocolDecoder.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -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; - -public class TytanProtocolDecoder extends BaseProtocolDecoder { - - public TytanProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void decodeExtraData(Position position, ByteBuf buf, int end) { - while (buf.readerIndex() < end) { - - int type = buf.readUnsignedByte(); - int length = buf.readUnsignedByte(); - if (length == 255) { - length += buf.readUnsignedByte(); - } - - int n; - - switch (type) { - case 2: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedMedium()); - break; - case 5: - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - break; - case 6: - n = buf.readUnsignedByte() >> 4; - if (n < 2) { - position.set(Position.PREFIX_ADC + n, buf.readFloat()); - } else { - position.set("di" + (n - 2), buf.readFloat()); - } - break; - case 7: - int alarm = buf.readUnsignedByte(); - buf.readUnsignedByte(); - if (BitUtil.check(alarm, 5)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - break; - case 8: - position.set("antihijack", buf.readUnsignedByte()); - break; - case 9: - position.set("unauthorized", ByteBufUtil.hexDump(buf.readSlice(8))); - break; - case 10: - position.set("authorized", ByteBufUtil.hexDump(buf.readSlice(8))); - break; - case 24: - for (int i = 0; i < length / 2; i++) { - position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readByte()); - } - break; - case 28: - position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedShort()); - buf.readUnsignedByte(); - break; - case 90: - position.set(Position.KEY_POWER, buf.readFloat()); - break; - case 101: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - break; - case 102: - position.set(Position.KEY_RPM, buf.readUnsignedByte() * 50); - break; - case 107: - int fuel = buf.readUnsignedShort(); - int fuelFormat = fuel >> 14; - if (fuelFormat == 1) { - position.set("fuelValue", (fuel & 0x3fff) * 0.4 + "%"); - } else if (fuelFormat == 2) { - position.set("fuelValue", (fuel & 0x3fff) * 0.5 + " l"); - } else if (fuelFormat == 3) { - position.set("fuelValue", (fuel & 0x3fff) * -0.5 + " l"); - } - break; - case 108: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); - break; - case 150: - position.set(Position.KEY_DOOR, buf.readUnsignedByte()); - break; - default: - buf.skipBytes(length); - break; - } - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.readUnsignedByte(); // protocol - buf.readUnsignedShort(); // length - int index = buf.readUnsignedByte() >> 3; - - if (channel != null) { - ByteBuf response = Unpooled.copiedBuffer("^" + index, StandardCharsets.US_ASCII); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - String id = String.valueOf(buf.readUnsignedInt()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - List<Position> positions = new LinkedList<>(); - - while (buf.readableBytes() > 2) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - int end = buf.readerIndex() + buf.readUnsignedByte(); - - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - - int flags = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, BitUtil.from(flags, 2)); - position.setValid(BitUtil.to(flags, 2) > 0); - - // Latitude - double lat = buf.readUnsignedMedium(); - lat = lat * -180 / 16777216 + 90; - position.setLatitude(lat); - - // Longitude - double lon = buf.readUnsignedMedium(); - lon = lon * 360 / 16777216 - 180; - position.setLongitude(lon); - - // Status - flags = buf.readUnsignedByte(); - position.set(Position.KEY_IGNITION, BitUtil.check(flags, 0)); - position.set(Position.KEY_RSSI, BitUtil.between(flags, 2, 5)); - position.setCourse((BitUtil.from(flags, 5) * 45 + 180) % 360); - - // Speed - int speed = buf.readUnsignedByte(); - if (speed < 250) { - position.setSpeed(UnitsConverter.knotsFromKph(speed)); - } - - decodeExtraData(position, buf, end); - - positions.add(position); - } - - return positions; - } - -} diff --git a/src/org/traccar/protocol/TzoneProtocol.java b/src/org/traccar/protocol/TzoneProtocol.java deleted file mode 100644 index 6e855d138..000000000 --- a/src/org/traccar/protocol/TzoneProtocol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.LengthFieldBasedFrameDecoder; - -public class TzoneProtocol extends BaseProtocol { - - public TzoneProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); - pipeline.addLast(new TzoneProtocolDecoder(TzoneProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java deleted file mode 100644 index 87b44a4b2..000000000 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * 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. - * 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.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; - -import java.net.SocketAddress; - -public class TzoneProtocolDecoder extends BaseProtocolDecoder { - - public TzoneProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private String decodeAlarm(Short value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x14: - return Position.ALARM_BRAKING; - case 0x15: - return Position.ALARM_ACCELERATION; - case 0x30: - return Position.ALARM_PARKING; - case 0x42: - return Position.ALARM_GEOFENCE_EXIT; - case 0x43: - return Position.ALARM_GEOFENCE_ENTER; - default: - return null; - } - } - - private boolean decodeGps(Position position, ByteBuf buf, int hardware) { - - int blockLength = buf.readUnsignedShort(); - int blockEnd = buf.readerIndex() + blockLength; - - if (blockLength < 22) { - return false; - } - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - - double lat; - double lon; - - if (hardware == 0x10A || hardware == 0x10B) { - lat = buf.readUnsignedInt() / 600000.0; - lon = buf.readUnsignedInt() / 600000.0; - } else { - lat = buf.readUnsignedInt() / 100000.0 / 60.0; - lon = buf.readUnsignedInt() / 100000.0 / 60.0; - } - - position.setFixTime(new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); - - position.setSpeed(buf.readUnsignedShort() * 0.01); - - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); - - int flags = buf.readUnsignedShort(); - position.setCourse(BitUtil.to(flags, 9)); - if (!BitUtil.check(flags, 10)) { - lat = -lat; - } - position.setLatitude(lat); - if (BitUtil.check(flags, 9)) { - lon = -lon; - } - position.setLongitude(lon); - position.setValid(BitUtil.check(flags, 11)); - - buf.readerIndex(blockEnd); - - return true; - } - - private void decodeCards(Position position, ByteBuf buf) { - - int index = 1; - for (int i = 0; i < 4; i++) { - - int blockLength = buf.readUnsignedShort(); - int blockEnd = buf.readerIndex() + blockLength; - - if (blockLength > 0) { - - int count = buf.readUnsignedByte(); - for (int j = 0; j < count; j++) { - - int length = buf.readUnsignedByte(); - - boolean odd = length % 2 != 0; - if (odd) { - length += 1; - } - - String num = ByteBufUtil.hexDump(buf.readSlice(length / 2)); - - if (odd) { - num = num.substring(1); - } - - position.set("card" + index, num); - } - } - - buf.readerIndex(blockEnd); - } - - } - - private void decodePassengers(Position position, ByteBuf buf) { - - int blockLength = buf.readUnsignedShort(); - int blockEnd = buf.readerIndex() + blockLength; - - if (blockLength > 0) { - - position.set("passengersOn", buf.readUnsignedMedium()); - position.set("passengersOff", buf.readUnsignedMedium()); - - } - - buf.readerIndex(blockEnd); - - } - - private void decodeTags(Position position, ByteBuf buf) { - - int blockLength = buf.readUnsignedShort(); - int blockEnd = buf.readerIndex() + blockLength; - - if (blockLength > 0) { - - buf.readUnsignedByte(); // tag type - - int count = buf.readUnsignedByte(); - int tagLength = buf.readUnsignedByte(); - - for (int i = 1; i <= count; i++) { - int tagEnd = buf.readerIndex() + tagLength; - - buf.readUnsignedByte(); // status - buf.readUnsignedShortLE(); // battery voltage - - position.set(Position.PREFIX_TEMP + i, (buf.readShortLE() & 0x3fff) * 0.1); - - buf.readUnsignedByte(); // humidity - buf.readUnsignedByte(); // rssi - - buf.readerIndex(tagEnd); - } - - } - - buf.readerIndex(blockEnd); - - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(2); // header - buf.readUnsignedShort(); // length - if (buf.readUnsignedShort() != 0x2424) { - return null; - } - int hardware = buf.readUnsignedShort(); - long firmware = buf.readUnsignedInt(); - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VERSION_HW, hardware); - position.set(Position.KEY_VERSION_FW, firmware); - - position.setDeviceTime(new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); - - // GPS info - - if (hardware == 0x406 || !decodeGps(position, buf, hardware)) { - - getLastLocation(position, position.getDeviceTime()); - - } - - // LBS info - - int blockLength = buf.readUnsignedShort(); - int blockEnd = buf.readerIndex() + blockLength; - - if (blockLength > 0 && (hardware == 0x10A || hardware == 0x10B || hardware == 0x406)) { - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); - } - - buf.readerIndex(blockEnd); - - // Status info - - blockLength = buf.readUnsignedShort(); - blockEnd = buf.readerIndex() + blockLength; - - if (blockLength >= 13) { - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - position.set("terminalInfo", buf.readUnsignedByte()); - - int status = buf.readUnsignedByte(); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1)); - status = buf.readUnsignedByte(); - position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4)); - if (BitUtil.check(status, 0)) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set("gsmStatus", buf.readUnsignedByte()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - } - - if (blockLength >= 15) { - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); - } - - buf.readerIndex(blockEnd); - - if (hardware == 0x10B) { - - decodeCards(position, buf); - - buf.skipBytes(buf.readUnsignedShort()); // temperature - buf.skipBytes(buf.readUnsignedShort()); // lock - - decodePassengers(position, buf); - - } - - if (hardware == 0x406) { - - decodeTags(position, buf); - - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/UlbotechFrameDecoder.java b/src/org/traccar/protocol/UlbotechFrameDecoder.java deleted file mode 100644 index f141dc9b7..000000000 --- a/src/org/traccar/protocol/UlbotechFrameDecoder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 2) { - return null; - } - - if (buf.getUnsignedByte(buf.readerIndex()) == 0xF8) { - - int index = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 0xF8); - if (index != -1) { - ByteBuf result = Unpooled.buffer(index + 1 - buf.readerIndex()); - - while (buf.readerIndex() <= index) { - int b = buf.readUnsignedByte(); - if (b == 0xF7) { - int ext = buf.readUnsignedByte(); - if (ext == 0x00) { - result.writeByte(0xF7); - } else if (ext == 0x0F) { - result.writeByte(0xF8); - } - } else { - result.writeByte(b); - } - } - - return result; - } - - } else { - - int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); - if (index != -1) { - return buf.readRetainedSlice(index + 1 - buf.readerIndex()); - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/UlbotechProtocol.java b/src/org/traccar/protocol/UlbotechProtocol.java deleted file mode 100644 index b99ec1cc6..000000000 --- a/src/org/traccar/protocol/UlbotechProtocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class UlbotechProtocol extends BaseProtocol { - - public UlbotechProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new UlbotechFrameDecoder()); - pipeline.addLast(new UlbotechProtocolDecoder(UlbotechProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java deleted file mode 100644 index 0a2a59e23..000000000 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 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. - * 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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.ObdDecoder; -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.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.regex.Pattern; - -public class UlbotechProtocolDecoder extends BaseProtocolDecoder { - - public UlbotechProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final short DATA_GPS = 0x01; - private static final short DATA_LBS = 0x02; - private static final short DATA_STATUS = 0x03; - private static final short DATA_ODOMETER = 0x04; - private static final short DATA_ADC = 0x05; - private static final short DATA_GEOFENCE = 0x06; - private static final short DATA_OBD2 = 0x07; - private static final short DATA_FUEL = 0x08; - private static final short DATA_OBD2_ALARM = 0x09; - private static final short DATA_HARSH_DRIVER = 0x0A; - private static final short DATA_CANBUS = 0x0B; - private static final short DATA_J1708 = 0x0C; - private static final short DATA_VIN = 0x0D; - private static final short DATA_RFID = 0x0E; - private static final short DATA_EVENT = 0x10; - - 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, ByteBufUtil.hexDump(buf.readSlice(parameterLength - 1)))); - } - } - - private void decodeJ1708(Position position, ByteBuf buf, int length) { - - int end = buf.readerIndex() + length; - - while (buf.readerIndex() < end) { - int mark = buf.readUnsignedByte(); - int len = BitUtil.between(mark, 0, 6); - int type = BitUtil.between(mark, 6, 8); - int id = buf.readUnsignedByte(); - if (type == 3) { - id += 256; - } - String value = ByteBufUtil.hexDump(buf.readSlice(len - 1)); - if (type == 2 || type == 3) { - position.set("pid" + id, value); - } - } - } - - private void decodeDriverBehavior(Position position, ByteBuf buf) { - - int value = buf.readUnsignedByte(); - - if (BitUtil.check(value, 0)) { - position.set("rapidAcceleration", true); - } - if (BitUtil.check(value, 1)) { - position.set("roughBraking", true); - } - if (BitUtil.check(value, 2)) { - position.set("harshCourse", true); - } - if (BitUtil.check(value, 3)) { - position.set("noWarmUp", true); - } - if (BitUtil.check(value, 4)) { - position.set("longIdle", true); - } - if (BitUtil.check(value, 5)) { - position.set("fatigueDriving", true); - } - if (BitUtil.check(value, 6)) { - position.set("roughTerrain", true); - } - if (BitUtil.check(value, 7)) { - position.set("highRpm", true); - } - } - - private String decodeAlarm(int alarm) { - if (BitUtil.check(alarm, 0)) { - return Position.ALARM_POWER_OFF; - } - if (BitUtil.check(alarm, 1)) { - return Position.ALARM_MOVEMENT; - } - if (BitUtil.check(alarm, 2)) { - return Position.ALARM_OVERSPEED; - } - if (BitUtil.check(alarm, 4)) { - return Position.ALARM_GEOFENCE; - } - if (BitUtil.check(alarm, 10)) { - return Position.ALARM_SOS; - } - return null; - } - - 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); - value = BitUtil.to(value, 12); - switch (id) { - case 0: - position.set(Position.KEY_POWER, value * (100 + 10) / 4096.0 - 10); - break; - case 1: - position.set(Position.PREFIX_TEMP + 1, value * (125 + 55) / 4096.0 - 55); - break; - case 2: - position.set(Position.KEY_BATTERY, value * (100 + 10) / 4096.0 - 10); - break; - case 3: - position.set(Position.PREFIX_ADC + 1, value * (100 + 10) / 4096.0 - 10); - break; - default: - position.set(Position.PREFIX_IO + id, value); - break; - } - } - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*TS") - .number("dd,") // protocol version - .number("(d{15}),") // device id - .number("(dd)(dd)(dd)") // time - .number("(dd)(dd)(dd),") // date - .expression("([^#]+)") // command - .text("#") - .compile(); - - private Object decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - - 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()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)) - .setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - getLastLocation(position, dateBuilder.getDate()); - - position.set(Position.KEY_RESULT, parser.next()); - - return position; - } - - private Object decodeBinary(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - - buf.readUnsignedByte(); // header - buf.readUnsignedByte(); // version - buf.readUnsignedByte(); // type - - String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - long seconds = buf.readUnsignedInt() & 0x7fffffffL; - seconds += 946684800L; // 2000-01-01 00:00 - seconds -= deviceSession.getTimeZone().getRawOffset() / 1000; - Date time = new Date(seconds * 1000); - - boolean hasLocation = false; - - while (buf.readableBytes() > 3) { - - int type = buf.readUnsignedByte(); - int length = type == DATA_CANBUS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - - switch (type) { - - case DATA_GPS: - hasLocation = true; - position.setValid(true); - position.setLatitude(buf.readInt() / 1000000.0); - position.setLongitude(buf.readInt() / 1000000.0); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - position.setCourse(buf.readUnsignedShort()); - position.set(Position.KEY_HDOP, buf.readUnsignedShort()); - break; - - case DATA_LBS: - if (length == 11) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedInt(), -buf.readUnsignedByte()))); - } else { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedShort(), -buf.readUnsignedByte()))); - } - if (length > 9 && length != 11) { - buf.skipBytes(length - 9); - } - break; - - case DATA_STATUS: - int status = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(status, 9)); - position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedShort())); - break; - - case DATA_ODOMETER: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - - case DATA_ADC: - decodeAdc(position, buf, length); - break; - - case DATA_GEOFENCE: - position.set("geofenceIn", buf.readUnsignedInt()); - position.set("geofenceAlarm", buf.readUnsignedInt()); - break; - - case DATA_OBD2: - decodeObd(position, buf, length); - break; - - case DATA_FUEL: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt() / 10000.0); - break; - - case DATA_OBD2_ALARM: - decodeObd(position, buf, length); - break; - - case DATA_HARSH_DRIVER: - decodeDriverBehavior(position, buf); - break; - - case DATA_CANBUS: - position.set("can", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - - case DATA_J1708: - decodeJ1708(position, buf, length); - break; - - case DATA_VIN: - position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); - break; - - case DATA_RFID: - position.set(Position.KEY_DRIVER_UNIQUE_ID, - buf.readSlice(length - 1).toString(StandardCharsets.US_ASCII)); - position.set("authorized", buf.readUnsignedByte() != 0); - break; - - case DATA_EVENT: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - if (length > 1) { - position.set("eventMask", buf.readUnsignedInt()); - } - break; - - default: - buf.skipBytes(length); - break; - } - } - - if (!hasLocation) { - getLastLocation(position, time); - } else { - position.setTime(time); - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (buf.getUnsignedByte(buf.readerIndex()) == 0xF8) { - - if (channel != null) { - 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.nioBuffer(1, 4))); - response.writeByte(0xF8); - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } - - return decodeBinary(channel, remoteAddress, buf); - } else { - - if (channel != null) { - 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 deleted file mode 100644 index 4e60ffeb6..000000000 --- a/src/org/traccar/protocol/UproProtocol.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * 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.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - -public class UproProtocol extends BaseProtocol { - - public UproProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new UproProtocolDecoder(UproProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/UproProtocolDecoder.java b/src/org/traccar/protocol/UproProtocolDecoder.java deleted file mode 100644 index dc7a9200d..000000000 --- a/src/org/traccar/protocol/UproProtocolDecoder.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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.protocol; - -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.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -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.regex.Pattern; - -public class UproProtocolDecoder extends BaseProtocolDecoder { - - public UproProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_HEADER = new PatternBuilder() - .text("*") - .expression("(..20)") // head - .expression("([01])") // ack - .number("(d+),") // device id - .expression("(.)") // type - .expression("(.)") // subtype - .any() - .compile(); - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(dd)(dd)(dddd)") // latitude - .number("(ddd)(dd)(dddd)") // longitude - .number("(d)") // flags - .number("(dd)") // speed - .number("(dd)") // course - .number("(dd)(dd)(dd)") // date (ddmmyy) - .compile(); - - private void decodeLocation(Position position, String data) { - Parser parser = new Parser(PATTERN_LOCATION, data); - if (parser.matches()) { - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - - int flags = parser.nextInt(0); - position.setValid(BitUtil.check(flags, 0)); - if (!BitUtil.check(flags, 1)) { - position.setLatitude(-position.getLatitude()); - } - if (!BitUtil.check(flags, 2)) { - position.setLongitude(-position.getLongitude()); - } - - position.setSpeed(parser.nextInt(0) * 2); - position.setCourse(parser.nextInt(0) * 10); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (buf.getByte(buf.readerIndex()) != '*') { - return null; - } - - int headerIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '&'); - if (headerIndex < 0) { - headerIndex = buf.writerIndex(); - } - String header = buf.readSlice(headerIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); - - Parser parser = new Parser(PATTERN_HEADER, header); - if (!parser.matches()) { - return null; - } - - String head = parser.next(); - boolean reply = parser.next().equals("1"); - - 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 subtype = parser.next(); - - if (reply && channel != null) { - channel.writeAndFlush(new NetworkMessage("*" + head + "Y" + type + subtype + "#", remoteAddress)); - } - - while (buf.isReadable()) { - - buf.readByte(); // skip delimiter - - byte dataType = buf.readByte(); - - int delimiterIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '&'); - if (delimiterIndex < 0) { - delimiterIndex = buf.writerIndex(); - } - - ByteBuf data = buf.readSlice(delimiterIndex - buf.readerIndex()); - - switch (dataType) { - case 'A': - decodeLocation(position, data.toString(StandardCharsets.US_ASCII)); - break; - case 'B': - position.set(Position.KEY_STATUS, data.toString(StandardCharsets.US_ASCII)); - break; - case 'C': - long odometer = 0; - while (data.isReadable()) { - odometer <<= 4; - odometer += data.readByte() - (byte) '0'; - } - position.set(Position.KEY_ODOMETER, odometer * 2 * 1852 / 3600); - break; - case 'F': - position.setSpeed( - Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); - break; - case 'K': - position.set("statusExtended", data.toString(StandardCharsets.US_ASCII)); - break; - case 'P': - if (data.readableBytes() >= 16) { - position.setNetwork(new Network(CellTower.from( - 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("obdPid", ByteBufUtil.hexDump(data)); - break; - case 'R': - if (head.startsWith("HQ")) { - position.set(Position.KEY_RSSI, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - position.set(Position.KEY_SATELLITES, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - } else { - position.set("odbTravel", ByteBufUtil.hexDump(data)); - } - break; - case 'S': - position.set("obdTraffic", ByteBufUtil.hexDump(data)); - break; - case 'T': - position.set(Position.KEY_BATTERY_LEVEL, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - break; - case 'V': - position.set(Position.KEY_POWER, - Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); - break; - default: - break; - } - - } - - if (position.getLatitude() != 0 && position.getLongitude() != 0) { - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/V680Protocol.java b/src/org/traccar/protocol/V680Protocol.java deleted file mode 100644 index dc0922cd4..000000000 --- a/src/org/traccar/protocol/V680Protocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * 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; - -public class V680Protocol extends BaseProtocol { - - public V680Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/V680ProtocolDecoder.java b/src/org/traccar/protocol/V680ProtocolDecoder.java deleted file mode 100644 index 0342404a6..000000000 --- a/src/org/traccar/protocol/V680ProtocolDecoder.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.util.regex.Pattern; - -public class V680ProtocolDecoder extends BaseProtocolDecoder { - - public V680ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .groupBegin() - .number("#(d+)#") // imei - .expression("([^#]*)#") // user - .groupEnd("?") - .number("(d+)#") // fix - .expression("([^#]+)#") // password - .expression("([^#]+)#") // event - .number("(d+)#") // packet number - .expression("([^#]+)?#?") // gsm base station - .expression("(?:[^#]+#)?") - .number("(d+.d+),([EW]),") // longitude - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),") // speed - .number("(d+.?d*)?#") // course - .number("(dd)(dd)(dd)#") // date (ddmmyy) - .number("(dd)(dd)(dd)") // time (hhmmss) - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - sentence = sentence.trim(); - - if (sentence.length() == 16) { - - getDeviceSession(channel, remoteAddress, sentence.substring(1, sentence.length())); - - } else { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession; - if (parser.hasNext()) { - deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.set("user", parser.next()); - position.setValid(parser.nextInt(0) > 0); - position.set("password", parser.next()); - position.set(Position.KEY_EVENT, parser.next()); - position.set("packet", parser.next()); - position.set("lbsData", parser.next()); - - double lon = parser.nextDouble(0); - boolean west = parser.next().equals("W"); - double lat = parser.nextDouble(0); - boolean south = parser.next().equals("S"); - - if (lat > 90 || lon > 180) { - int lonDegrees = (int) (lon * 0.01); - lon = (lon - lonDegrees * 100) / 60.0; - lon += lonDegrees; - - int latDegrees = (int) (lat * 0.01); - lat = (lat - latDegrees * 100) / 60.0; - lat += latDegrees; - } - - position.setLongitude(west ? -lon : lon); - position.setLatitude(south ? -lat : lat); - - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - - int day = parser.nextInt(0); - int month = parser.nextInt(0); - if (day == 0 && month == 0) { - return null; // invalid date - } - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(0), month, day) - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - return position; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/VisiontekProtocol.java b/src/org/traccar/protocol/VisiontekProtocol.java deleted file mode 100644 index 2c6af45a8..000000000 --- a/src/org/traccar/protocol/VisiontekProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class VisiontekProtocol extends BaseProtocol { - - public VisiontekProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new VisiontekProtocolDecoder(VisiontekProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java deleted file mode 100644 index c4787bda2..000000000 --- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 VisiontekProtocolDecoder extends BaseProtocolDecoder { - - public VisiontekProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("$1,") - .expression("([^,]+),") // identifier - .number("(d+),").optional() // imei - .number("(dd),(dd),(dd),") // date (dd,mm,yy) - .number("(dd),(dd),(dd),") // time (hh,mm,ss) - .groupBegin() - .number("(dd)(dd).?(d+)([NS]),") // latitude - .number("(ddd)(dd).?(d+)([EW]),") // longitude - .or() - .number("(dd.d+)([NS]),") // latitude - .number("(ddd.d+)([EW]),") // longitude - .groupEnd() - .number("(d+.?d+),") // speed - .number("(d+),") // course - .groupBegin() - .number("(d+),") // altitude - .number("(d+),") // satellites - .number("(d+),") // odometer - .number("([01]),") // ignition - .number("([01]),") // input 1 - .number("([01]),") // input 2 - .number("([01]),") // immobilizer - .number("([01]),") // external battery status - .number("(d+),") // gsm - .or() - .number("(d+.d),") // hdop - .number("(d+),") // altitude - .number("(d+),") // odometer - .number("([01],[01],[01],[01]),") // input - .number("([01],[01],[01],[01]),") // output - .number("(d+.?d*),") // adc 1 - .number("(d+.?d*),") // adc 2 - .groupEnd("?") - .any() - .expression("([AV])") // validity - .number(",(d{10})").optional() // rfid - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - if (parser.hasNext(8)) { - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - } - if (parser.hasNext(4)) { - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - } - - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble( - parser.next().replace(".", "")) / 10)); - - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext(9)) { - position.setAltitude(parser.nextDouble(0)); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0) * 1000); - position.set(Position.KEY_IGNITION, parser.next().equals("1")); - position.set(Position.PREFIX_IO + 1, parser.next()); - position.set(Position.PREFIX_IO + 2, parser.next()); - position.set("immobilizer", parser.next()); - position.set(Position.KEY_CHARGE, parser.next().equals("1")); - position.set(Position.KEY_RSSI, parser.nextDouble()); - } - - if (parser.hasNext(7)) { - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.setAltitude(parser.nextDouble(0)); - position.set(Position.KEY_ODOMETER, parser.nextInt(0) * 1000); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - } - - position.setValid(parser.next().equals("A")); - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Vt200FrameDecoder.java b/src/org/traccar/protocol/Vt200FrameDecoder.java deleted file mode 100644 index 0fd83e715..000000000 --- a/src/org/traccar/protocol/Vt200FrameDecoder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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, ByteBuf buf) throws Exception { - - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ')') + 1; - if (endIndex > 0) { - - ByteBuf frame = Unpooled.buffer(); - - while (buf.readerIndex() < endIndex) { - int b = buf.readByte(); - if (b == '=') { - frame.writeByte(buf.readByte() ^ '='); - } else { - frame.writeByte(b); - } - } - - return frame; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/Vt200Protocol.java b/src/org/traccar/protocol/Vt200Protocol.java deleted file mode 100644 index 2a9ef6ab5..000000000 --- a/src/org/traccar/protocol/Vt200Protocol.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * 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; - -public class Vt200Protocol extends BaseProtocol { - - public Vt200Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Vt200FrameDecoder()); - pipeline.addLast(new Vt200ProtocolDecoder(Vt200Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java deleted file mode 100644 index b1564abd9..000000000 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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. - * 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.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.BcdUtil; -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.util.Arrays; -import java.util.Date; - -public class Vt200ProtocolDecoder extends BaseProtocolDecoder { - - public Vt200ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static double decodeCoordinate(int value) { - int degrees = value / 1000000; - int minutes = value % 1000000; - return degrees + minutes * 0.0001 / 60; - } - - 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)); - return dateBuilder.getDate(); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(1); // header - - String id = ByteBufUtil.hexDump(buf.readSlice(6)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - int type = buf.readUnsignedShort(); - buf.readUnsignedShort(); // length - - if (type == 0x2086 || type == 0x2084 || type == 0x2082) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - buf.readUnsignedByte(); // data type - buf.readUnsignedShort(); // trip id - - position.setTime(decodeDate(buf)); - - position.setLatitude(decodeCoordinate(BcdUtil.readInteger(buf, 8))); - position.setLongitude(decodeCoordinate(BcdUtil.readInteger(buf, 9))); - - int flags = buf.readUnsignedByte(); - position.setValid(BitUtil.check(flags, 0)); - if (!BitUtil.check(flags, 1)) { - position.setLatitude(-position.getLatitude()); - } - if (!BitUtil.check(flags, 2)) { - position.setLongitude(-position.getLongitude()); - } - - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.setCourse(buf.readUnsignedByte() * 2); - - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - - // additional data - - return position; - - } else if (type == 0x3088) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - buf.readUnsignedShort(); // trip id - buf.skipBytes(8); // imei - buf.skipBytes(8); // imsi - - position.set("tripStart", decodeDate(buf).getTime()); - position.set("tripEnd", decodeDate(buf).getTime()); - position.set("drivingTime", buf.readUnsignedShort()); - - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); - - position.set("maxSpeed", UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.set("maxRpm", buf.readUnsignedShort()); - position.set("maxTemp", buf.readUnsignedByte() - 40); - position.set("hardAccelerationCount", buf.readUnsignedByte()); - position.set("hardBrakingCount", buf.readUnsignedByte()); - - for (String speedType : Arrays.asList("over", "high", "normal", "low")) { - position.set(speedType + "SpeedTime", buf.readUnsignedShort()); - position.set(speedType + "SpeedDistance", buf.readUnsignedInt()); - position.set(speedType + "SpeedFuel", buf.readUnsignedInt()); - } - - position.set("idleTime", buf.readUnsignedShort()); - position.set("idleFuel", buf.readUnsignedInt()); - - position.set("hardCorneringCount", buf.readUnsignedByte()); - position.set("overspeedCount", buf.readUnsignedByte()); - position.set("overheatCount", buf.readUnsignedShort()); - position.set("laneChangeCount", buf.readUnsignedByte()); - position.set("emergencyRefueling", buf.readUnsignedByte()); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/VtfmsFrameDecoder.java b/src/org/traccar/protocol/VtfmsFrameDecoder.java deleted file mode 100644 index 62a189960..000000000 --- a/src/org/traccar/protocol/VtfmsFrameDecoder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; - -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, 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.readRetainedSlice(endIndex - buf.readerIndex()); - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/VtfmsProtocol.java b/src/org/traccar/protocol/VtfmsProtocol.java deleted file mode 100644 index 2826a86e6..000000000 --- a/src/org/traccar/protocol/VtfmsProtocol.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.string.StringDecoder; - -public class VtfmsProtocol extends BaseProtocol { - - public VtfmsProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new VtfmsFrameDecoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/org/traccar/protocol/VtfmsProtocolDecoder.java deleted file mode 100644 index 17fac4311..000000000 --- a/src/org/traccar/protocol/VtfmsProtocolDecoder.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2017 - 2019 Anton Tananaev (anton@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.Protocol; -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 VtfmsProtocolDecoder extends BaseProtocolDecoder { - - private static final String[] DIRECTIONS = new String[] {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}; - - public VtfmsProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("(") - .number("(d{15}),") // imei - .number("[0-9A-Z]{3}dd,") // packet count - .number("(dd),") // packet id - .number("[^,]*,") // reserved - .number("(d+)?,") // rssi - .number("(?:d+)?,") // fix status - .number("(d+)?,") // satellites - .number("[^,]*,") // reserved - .expression("([AV]),") // validity - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(dd)(dd)(dd),") // time (ddmmyy) - .number("(-?d+.d+),") // latitude - .number("(-?d+.d+),") // longitude - .number("(?:(d+)|([NESW]{1,2})),") // course - .number("(d+),") // speed - .number("(d+),") // hours - .number("(d+),") // idle hours - .expression("[KNT],") // antenna status - .number("(d+),") // odometer - .expression("([01]),") // power status - .number("(d+.d+),") // power voltage - .number("[^,]*,") // reserved - .number("(d+)?,") // fuel level - .number("(d+.d+)?,") // adc 1 - .number("[^,]*,") // reserved - .number("(d+.d+)?,") // adc 2 - .expression("([01]),") // di 1 - .expression("([01]),") // di 2 - .expression("([01]),") // di 3 - .expression("([01]),") // di 4 - .expression("([01]),") // do 1 - .expression("([01]),") // do 2 - .expression("([01]),") // do 3 - .number("[^,]*,") // reserved - .number("[^,]*") // reserved - .text(")") - .number("ddd") // checksum - .compile(); - - private String decodeAlarm(int value) { - switch (value) { - case 10: - return Position.ALARM_OVERSPEED; - case 14: - return Position.ALARM_POWER_CUT; - case 15: - return Position.ALARM_POWER_RESTORED; - case 32: - return Position.ALARM_BRAKING; - case 33: - return Position.ALARM_ACCELERATION; - default: - return null; - } - } - - private double convertToDegrees(double value) { - double degrees = Math.floor(value / 100); - return degrees + (value - degrees * 100) / 60; - } - - @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.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt())); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setValid(parser.next().equals("A")); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY)); - - double latitude = parser.nextDouble(); - double longitude = parser.nextDouble(); - if (Math.abs(latitude) > 90 || Math.abs(longitude) > 180) { - position.setLatitude(convertToDegrees(latitude)); - position.setLongitude(convertToDegrees(longitude)); - } else { - position.setLatitude(latitude); - position.setLongitude(longitude); - } - - position.setCourse(parser.nextDouble(0)); - if (parser.hasNext()) { - String direction = parser.next(); - for (int i = 0; i < DIRECTIONS.length; i++) { - if (direction.equals(DIRECTIONS[i])) { - position.setCourse(i * 45.0); - break; - } - } - } - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - 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")); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); - position.set(Position.PREFIX_IN + 1, parser.nextInt()); - position.set(Position.PREFIX_IN + 2, parser.nextInt()); - position.set(Position.PREFIX_IN + 3, parser.nextInt()); - position.set(Position.PREFIX_IN + 4, parser.nextInt()); - position.set(Position.PREFIX_OUT + 1, parser.nextInt()); - position.set(Position.PREFIX_OUT + 2, parser.nextInt()); - position.set(Position.PREFIX_OUT + 3, parser.nextInt()); - - return position; - } - -} diff --git a/src/org/traccar/protocol/WatchFrameDecoder.java b/src/org/traccar/protocol/WatchFrameDecoder.java deleted file mode 100644 index f99bd52e2..000000000 --- a/src/org/traccar/protocol/WatchFrameDecoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - * 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 io.netty.channel.ChannelHandlerContext; -import org.traccar.BaseFrameDecoder; - -public class WatchFrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ']') + 1; - if (endIndex > 0) { - ByteBuf frame = Unpooled.buffer(); - while (buf.readerIndex() < endIndex) { - byte b1 = buf.readByte(); - if (b1 == '}') { - byte b2 = buf.readByte(); - switch (b2) { - case 0x01: - frame.writeByte('}'); - break; - case 0x02: - frame.writeByte('['); - break; - case 0x03: - frame.writeByte(']'); - break; - case 0x04: - frame.writeByte(','); - break; - case 0x05: - frame.writeByte('*'); - break; - default: - throw new IllegalArgumentException(String.format( - "unexpected byte at %d: 0x%02x", buf.readerIndex() - 1, b2)); - } - } else { - frame.writeByte(b1); - } - } - return frame; - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java deleted file mode 100644 index fe285e70d..000000000 --- a/src/org/traccar/protocol/WatchProtocol.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -public class WatchProtocol extends BaseProtocol { - - public WatchProtocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_SOS_NUMBER, - Command.TYPE_ALARM_SOS, - Command.TYPE_ALARM_BATTERY, - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_POWER_OFF, - Command.TYPE_ALARM_REMOVE, - Command.TYPE_SILENCE_TIME, - Command.TYPE_ALARM_CLOCK, - Command.TYPE_SET_PHONEBOOK, - Command.TYPE_MESSAGE, - Command.TYPE_VOICE_MESSAGE, - Command.TYPE_SET_TIMEZONE, - Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new WatchFrameDecoder()); - pipeline.addLast(new WatchProtocolEncoder()); - pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java deleted file mode 100644 index 70b207e9b..000000000 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -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 org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.regex.Pattern; - -public class WatchProtocolDecoder extends BaseProtocolDecoder { - - private static final Logger LOGGER = LoggerFactory.getLogger(WatchProtocolDecoder.class); - - public WatchProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN_POSITION = new PatternBuilder() - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number(" *(-?d+.d+),") // latitude - .expression("([NS]),") - .number(" *(-?d+.d+),") // longitude - .expression("([EW])?,") - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+.?d*),") // altitude - .number("(d+),") // satellites - .number("(d+),") // rssi - .number("(d+),") // battery - .number("(d+),") // steps - .number("d+,") // tumbles - .number("(x+),") // status - .expression("(.*)") // cell and wifi - .compile(); - - private void sendResponse(Channel channel, String id, String index, String content) { - if (channel != null) { - String response; - if (index != null) { - response = String.format("[%s*%s*%s*%04x*%s]", - manufacturer, id, index, content.length(), content); - } else { - response = String.format("[%s*%s*%04x*%s]", - manufacturer, id, content.length(), content); - } - ByteBuf buf = Unpooled.copiedBuffer(response, StandardCharsets.US_ASCII); - channel.writeAndFlush(new NetworkMessage(buf, channel.remoteAddress())); - } - } - - private String decodeAlarm(int status) { - if (BitUtil.check(status, 0)) { - return Position.ALARM_LOW_BATTERY; - } else if (BitUtil.check(status, 1)) { - return Position.ALARM_GEOFENCE_EXIT; - } else if (BitUtil.check(status, 2)) { - return Position.ALARM_GEOFENCE_ENTER; - } else if (BitUtil.check(status, 3)) { - return Position.ALARM_OVERSPEED; - } else if (BitUtil.check(status, 16)) { - return Position.ALARM_SOS; - } else if (BitUtil.check(status, 17)) { - return Position.ALARM_LOW_BATTERY; - } else if (BitUtil.check(status, 18)) { - return Position.ALARM_GEOFENCE_EXIT; - } else if (BitUtil.check(status, 19)) { - return Position.ALARM_GEOFENCE_ENTER; - } else if (BitUtil.check(status, 20)) { - return Position.ALARM_REMOVING; - } else if (BitUtil.check(status, 21)) { - return Position.ALARM_FALL_DOWN; - } - return null; - } - - private Position decodePosition(DeviceSession deviceSession, String data) { - - Parser parser = new Parser(PATTERN_POSITION, data); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - position.set(Position.KEY_STEPS, parser.nextInt(0)); - - int status = parser.nextHexInt(0); - position.set(Position.KEY_ALARM, decodeAlarm(status)); - if (BitUtil.check(status, 4)) { - position.set(Position.KEY_MOTION, true); - } - - String[] values = parser.next().split(","); - int index = 0; - - Network network = new Network(); - - int cellCount = Integer.parseInt(values[index++]); - index += 1; // timing advance - int mcc = Integer.parseInt(values[index++]); - int mnc = Integer.parseInt(values[index++]); - - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from(mcc, mnc, - Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), - Integer.parseInt(values[index++]))); - } - - if (index < values.length && !values[index].isEmpty()) { - int wifiCount = Integer.parseInt(values[index++]); - - for (int i = 0; i < wifiCount; i++) { - index += 1; // wifi name - network.addWifiAccessPoint(WifiAccessPoint.from( - values[index++], Integer.parseInt(values[index++]))); - } - } - - if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { - position.setNetwork(network); - } - - 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 { - - ByteBuf buf = (ByteBuf) msg; - - buf.skipBytes(1); // '[' header - manufacturer = buf.readSlice(2).toString(StandardCharsets.US_ASCII); - buf.skipBytes(1); // '*' delimiter - - 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; - } - - buf.skipBytes(1); // '*' delimiter - - String index = null; - 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(); - hasIndex = true; - index = buf.readSlice(indexLength).toString(StandardCharsets.US_ASCII); - buf.skipBytes(1); // '*' delimiter - } - - buf.skipBytes(4); // length - buf.skipBytes(1); // '*' delimiter - - buf.writerIndex(buf.writerIndex() - 1); // ']' ignore ending - - contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - if (contentIndex < 0) { - contentIndex = buf.writerIndex(); - } - - String type = buf.readSlice(contentIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); - - if (contentIndex < buf.writerIndex()) { - buf.readerIndex(contentIndex + 1); - } - - if (type.equals("INIT")) { - - sendResponse(channel, id, index, "INIT,1"); - - } else if (type.equals("LK")) { - - sendResponse(channel, id, index, "LK"); - - if (buf.isReadable()) { - String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); - if (values.length >= 3) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[2])); - - return position; - } - } - - } 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")) { - if (position != null) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - sendResponse(channel, id, index, "AL"); - } - - return position; - - } else if (type.equals("TKQ")) { - - sendResponse(channel, id, index, "TKQ"); - - } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) { - - if (buf.isReadable()) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, new Date()); - - String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); - int valueIndex = 0; - - if (type.equals("bphrt")) { - position.set("pressureHigh", values[valueIndex++]); - position.set("pressureLow", values[valueIndex++]); - } - position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex])); - - return position; - - } - - } else if (type.equals("img")) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - int timeIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - buf.readerIndex(timeIndex + 12 + 2); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(id, buf, "jpg")); - - return position; - - } else if (type.equals("TK")) { - - if (buf.readableBytes() == 1) { - byte result = buf.readByte(); - if (result != '1') { - LOGGER.warn(type + "," + result); - } - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr")); - - return position; - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java deleted file mode 100644 index 264aec81f..000000000 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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. - * 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.StringProtocolEncoder; -import org.traccar.helper.DataConverter; -import org.traccar.model.Command; - -import java.nio.charset.StandardCharsets; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -public class WatchProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { - - @Override - public String formatValue(String key, Object value) { - if (key.equals(Command.KEY_TIMEZONE)) { - double offset = TimeZone.getTimeZone((String) value).getRawOffset() / 3600000.0; - DecimalFormat fmt = new DecimalFormat("+#.##;-#.##", DecimalFormatSymbols.getInstance(Locale.US)); - return fmt.format(offset); - } else if (key.equals(Command.KEY_MESSAGE)) { - return DataConverter.printHex(value.toString().getBytes(StandardCharsets.UTF_16BE)); - } else if (key.equals(Command.KEY_ENABLE)) { - return (boolean) value ? "1" : "0"; - } - - return null; - } - - protected ByteBuf formatTextCommand(Channel channel, Command command, String format, String... keys) { - String content = formatCommand(command, format, this, keys); - ByteBuf buf = Unpooled.copiedBuffer(content, StandardCharsets.US_ASCII); - - return formatBinaryCommand(channel, command, "", buf); - } - - protected ByteBuf formatBinaryCommand(Channel channel, Command command, String textPrefix, ByteBuf data) { - 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(); - } - } - - ByteBuf buf = Unpooled.buffer(); - buf.writeByte('['); - buf.writeCharSequence(manufacturer, StandardCharsets.US_ASCII); - buf.writeByte('*'); - buf.writeCharSequence(getUniqueId(command.getDeviceId()), StandardCharsets.US_ASCII); - buf.writeByte('*'); - if (hasIndex) { - buf.writeCharSequence("0001", StandardCharsets.US_ASCII); - buf.writeByte('*'); - } - buf.writeCharSequence(String.format("%04x", data.readableBytes() + textPrefix.length()), - StandardCharsets.US_ASCII); - buf.writeByte('*'); - buf.writeCharSequence(textPrefix, StandardCharsets.US_ASCII); - buf.writeBytes(data); - buf.writeByte(']'); - - return buf; - } - - private static Map<Byte, Byte> mapping = new HashMap<>(); - - static { - mapping.put((byte) 0x7d, (byte) 0x01); - mapping.put((byte) 0x5B, (byte) 0x02); - mapping.put((byte) 0x5D, (byte) 0x03); - mapping.put((byte) 0x2C, (byte) 0x04); - mapping.put((byte) 0x2A, (byte) 0x05); - } - - private ByteBuf getBinaryData(Command command) { - byte[] data = DataConverter.parseHex(command.getString(Command.KEY_DATA)); - - int encodedLength = data.length; - for (byte b : data) { - if (mapping.containsKey(b)) { - encodedLength += 1; - } - } - - int index = 0; - byte[] encodedData = new byte[encodedLength]; - - for (byte b : data) { - Byte replacement = mapping.get(b); - if (replacement != null) { - encodedData[index] = 0x7D; - index += 1; - encodedData[index] = replacement; - } else { - encodedData[index] = b; - } - index += 1; - } - - return Unpooled.copiedBuffer(encodedData); - } - - @Override - protected Object encodeCommand(Channel channel, Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatTextCommand(channel, command, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return formatTextCommand(channel, command, "RG"); - case Command.TYPE_SOS_NUMBER: - return formatTextCommand(channel, command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE); - case Command.TYPE_ALARM_SOS: - return formatTextCommand(channel, command, "SOSSMS,{%s}", Command.KEY_ENABLE); - case Command.TYPE_ALARM_BATTERY: - return formatTextCommand(channel, command, "LOWBAT,{%s}", Command.KEY_ENABLE); - case Command.TYPE_REBOOT_DEVICE: - return formatTextCommand(channel, command, "RESET"); - case Command.TYPE_POWER_OFF: - return formatTextCommand(channel, command, "POWEROFF"); - case Command.TYPE_ALARM_REMOVE: - return formatTextCommand(channel, command, "REMOVE,{%s}", Command.KEY_ENABLE); - case Command.TYPE_SILENCE_TIME: - return formatTextCommand(channel, command, "SILENCETIME,{%s}", Command.KEY_DATA); - case Command.TYPE_ALARM_CLOCK: - return formatTextCommand(channel, command, "REMIND,{%s}", Command.KEY_DATA); - case Command.TYPE_SET_PHONEBOOK: - return formatTextCommand(channel, command, "PHB,{%s}", Command.KEY_DATA); - case Command.TYPE_MESSAGE: - return formatTextCommand(channel, command, "MESSAGE,{%s}", Command.KEY_MESSAGE); - case Command.TYPE_VOICE_MESSAGE: - return formatBinaryCommand(channel, command, "TK,", getBinaryData(command)); - case Command.TYPE_POSITION_PERIODIC: - return formatTextCommand(channel, command, "UPLOAD,{%s}", Command.KEY_FREQUENCY); - case Command.TYPE_SET_TIMEZONE: - return formatTextCommand(channel, command, "LZ,,{%s}", Command.KEY_TIMEZONE); - case Command.TYPE_SET_INDICATOR: - return formatTextCommand(channel, command, "FLOWER,{%s}", Command.KEY_DATA); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/WialonProtocol.java b/src/org/traccar/protocol/WialonProtocol.java deleted file mode 100644 index 06b54dceb..000000000 --- a/src/org/traccar/protocol/WialonProtocol.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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.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; -public class WialonProtocol extends BaseProtocol { - - public WialonProtocol() { - setSupportedDataCommands( - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_SEND_USSD, - Command.TYPE_IDENTIFICATION, - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - pipeline.addLast(new StringEncoder()); - boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); - if (utf8) { - pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); - } else { - pipeline.addLast(new StringDecoder()); - } - pipeline.addLast(new WialonProtocolEncoder()); - pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java deleted file mode 100644 index de7073b67..000000000 --- a/src/org/traccar/protocol/WialonProtocolDecoder.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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. - * 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.Protocol; -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.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class WialonProtocolDecoder extends BaseProtocolDecoder { - - public WialonProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("(dd)(dd)(dd);") // date (ddmmyy) - .number("(dd)(dd)(dd);") // time (hhmmss) - .number("(dd)(dd.d+);") // latitude - .expression("([NS]);") - .number("(ddd)(dd.d+);") // longitude - .expression("([EW]);") - .number("(d+.?d*)?;") // speed - .number("(d+.?d*)?;") // course - .number("(?:NA|(-?d+.?d*));") // altitude - .number("(?:NA|(d+))") // satellites - .groupBegin().text(";") - .number("(?:NA|(d+.?d*));") // hdop - .number("(?:NA|(d+));") // inputs - .number("(?:NA|(d+));") // outputs - .expression("(?:NA|([^;]*));") // adc - .expression("(?:NA|([^;]*));") // ibutton - .expression("(?:NA|(.*))") // params - .groupEnd("?") - .compile(); - - 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.writeAndFlush(new NetworkMessage(response.toString(), remoteAddress)); - } - } - - private Position decodePosition(Channel channel, SocketAddress remoteAddress, String substring) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Parser parser = new Parser(PATTERN, substring); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext()) { - int satellites = parser.nextInt(0); - position.setValid(satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - } - - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - - if (parser.hasNext()) { - String[] values = parser.next().split(","); - for (int i = 0; i < values.length; i++) { - position.set(Position.PREFIX_ADC + (i + 1), values[i]); - } - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - if (parser.hasNext()) { - String[] values = parser.next().split(","); - for (String param : values) { - Matcher paramParser = Pattern.compile("(.*):[1-3]:(.*)").matcher(param); - if (paramParser.matches()) { - try { - position.set(paramParser.group(1).toLowerCase(), Double.parseDouble(paramParser.group(2))); - } catch (NumberFormatException e) { - position.set(paramParser.group(1).toLowerCase(), paramParser.group(2)); - } - } - } - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("#L#")) { - - String[] values = sentence.substring(3).split(";"); - - String imei = values[0].indexOf('.') >= 0 ? values[1] : values[0]; - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null) { - sendResponse(channel, remoteAddress, "#AL#", 1); - } - - } else if (sentence.startsWith("#P#")) { - - sendResponse(channel, remoteAddress, "#AP#", null); // heartbeat - - } else if (sentence.startsWith("#SD#") || sentence.startsWith("#D#")) { - - Position position = decodePosition( - channel, remoteAddress, sentence.substring(sentence.indexOf('#', 1) + 1)); - - if (position != null) { - sendResponse(channel, remoteAddress, "#AD#", 1); - return position; - } - - } else if (sentence.startsWith("#B#")) { - - String[] messages = sentence.substring(sentence.indexOf('#', 1) + 1).split("\\|"); - List<Position> positions = new LinkedList<>(); - - for (String message : messages) { - Position position = decodePosition(channel, remoteAddress, message); - if (position != null) { - position.set(Position.KEY_ARCHIVE, true); - positions.add(position); - } - } - - sendResponse(channel, remoteAddress, "#AB#", messages.length); - if (!positions.isEmpty()) { - return positions; - } - - } else if (sentence.startsWith("#M#")) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, new Date()); - position.setValid(false); - position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf('#', 1) + 1)); - sendResponse(channel, remoteAddress, "#AM#", 1); - return position; - } - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/WialonProtocolEncoder.java b/src/org/traccar/protocol/WialonProtocolEncoder.java deleted file mode 100644 index 9ff1631eb..000000000 --- a/src/org/traccar/protocol/WialonProtocolEncoder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.model.Command; - -public class WialonProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "reboot\r\n"); - case Command.TYPE_SEND_USSD: - return formatCommand(command, "USSD:{%s}\r\n", Command.KEY_PHONE); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "VER?\r\n"); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "L{%s}={%s}\r\n", Command.KEY_INDEX, Command.KEY_DATA); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/WondexFrameDecoder.java b/src/org/traccar/protocol/WondexFrameDecoder.java deleted file mode 100644 index 39d83d761..000000000 --- a/src/org/traccar/protocol/WondexFrameDecoder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - * 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.BaseFrameDecoder; -import org.traccar.NetworkMessage; -import org.traccar.helper.BufferUtil; - -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, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < KEEP_ALIVE_LENGTH) { - return null; - } - - if (buf.getUnsignedByte(buf.readerIndex()) == 0xD0) { - - // Send response - ByteBuf frame = buf.readRetainedSlice(KEEP_ALIVE_LENGTH); - if (channel != null) { - frame.retain(); - channel.writeAndFlush(new NetworkMessage(frame, channel.remoteAddress())); - } - return frame; - - } else { - - int index = BufferUtil.indexOf("\r\n", buf); - if (index != -1) { - ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex()); - buf.skipBytes(2); - return frame; - } - - } - - return null; - } - -} diff --git a/src/org/traccar/protocol/WondexProtocol.java b/src/org/traccar/protocol/WondexProtocol.java deleted file mode 100644 index 8c6283d66..000000000 --- a/src/org/traccar/protocol/WondexProtocol.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - * 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 org.traccar.model.Command; - -import io.netty.handler.codec.string.StringEncoder; - -public class WondexProtocol extends BaseProtocol { - - public WondexProtocol() { - setTextCommandEncoder(new WondexProtocolEncoder()); - setSupportedCommands( - Command.TYPE_GET_DEVICE_STATUS, - Command.TYPE_GET_MODEM_STATUS, - Command.TYPE_REBOOT_DEVICE, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_GET_VERSION, - Command.TYPE_IDENTIFICATION); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new WondexFrameDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new WondexProtocolEncoder()); - pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new WondexProtocolEncoder()); - pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/WondexProtocolDecoder.java b/src/org/traccar/protocol/WondexProtocolDecoder.java deleted file mode 100644 index b85ae2656..000000000 --- a/src/org/traccar/protocol/WondexProtocolDecoder.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.regex.Pattern; - -public class WondexProtocolDecoder extends BaseProtocolDecoder { - - public WondexProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("[^d]*") // header - .number("(d+),") // device identifier - .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+.?d*),") // altitude - .number("(d+),") // satellites - .number("(d+),?") // event - .number("(d+.d+)V,").optional() // battery - .number("(d+.d+)?,?") // odometer - .number("(d+)?,?") // input - .number("(d+.d+)?,?") // adc1 - .number("(d+.d+)?,?") // adc2 - .number("(d+)?") // output - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - if (buf.getUnsignedByte(0) == 0xD0) { - - long deviceId = ((Long.reverseBytes(buf.getLong(0))) >> 32) & 0xFFFFFFFFL; - getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); - - return null; - } else if (buf.toString(StandardCharsets.US_ASCII).startsWith("$OK:") - || buf.toString(StandardCharsets.US_ASCII).startsWith("$ERR:") - || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, new Date()); - position.set(Position.KEY_RESULT, buf.toString(StandardCharsets.US_ASCII)); - - return position; - - } else { - - Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII)); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - int satellites = parser.nextInt(0); - position.setValid(satellites != 0); - position.set(Position.KEY_SATELLITES, satellites); - - position.set(Position.KEY_EVENT, parser.next()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - } - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - - return position; - - } - - } - -} diff --git a/src/org/traccar/protocol/WondexProtocolEncoder.java b/src/org/traccar/protocol/WondexProtocolEncoder.java deleted file mode 100644 index f9e8eeb9b..000000000 --- a/src/org/traccar/protocol/WondexProtocolEncoder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.model.Command; - -public class WondexProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, "0000"); - - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "$WP+REBOOT={%s}", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_DEVICE_STATUS: - return formatCommand(command, "$WP+TEST={%s}", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_MODEM_STATUS: - return formatCommand(command, "$WP+GSMINFO={%s}", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "$WP+IMEI={%s}", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "$WP+GETLOCATION={%s}", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_VERSION: - return formatCommand(command, "$WP+VER={%s}", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/WristbandProtocol.java b/src/org/traccar/protocol/WristbandProtocol.java deleted file mode 100644 index 1e5ef2c01..000000000 --- a/src/org/traccar/protocol/WristbandProtocol.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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; - -public class WristbandProtocol extends BaseProtocol { - - public WristbandProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); - pipeline.addLast(new WristbandProtocolDecoder(WristbandProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/WristbandProtocolDecoder.java b/src/org/traccar/protocol/WristbandProtocolDecoder.java deleted file mode 100644 index 7f2b0af85..000000000 --- a/src/org/traccar/protocol/WristbandProtocolDecoder.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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.Protocol; -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 org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -public class WristbandProtocolDecoder extends BaseProtocolDecoder { - - public WristbandProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private void sendResponse( - Channel channel, String imei, String version, int type, String data) { - - if (channel != null) { - String sentence = String.format("YX%s|%s|0|{F%02d#%s}\r\n", imei, version, type, data); - ByteBuf response = Unpooled.buffer(); - if (type != 91) { - response.writeBytes(new byte[]{0x00, 0x01, 0x02}); - response.writeShort(sentence.length()); - } - response.writeCharSequence(sentence, StandardCharsets.US_ASCII); - if (type != 91) { - response.writeBytes(new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0xFC}); - } - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); - } - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("..") // header - .number("(d+)|") // imei - .number("([vV]d+.d+)|") // version - .number("d+|") // model - .text("{") - .number("F(d+)") // function - .groupBegin() - .text("#") - .expression("(.*)") // data - .groupEnd("?") - .text("}") - .text("\r\n") - .compile(); - - private Position decodePosition(DeviceSession deviceSession, String sentence) throws ParseException { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - String[] values = sentence.split(","); - - position.setValid(true); - position.setLongitude(Double.parseDouble(values[0])); - position.setLatitude(Double.parseDouble(values[1])); - position.setTime(new SimpleDateFormat("yyyyMMddHHmm").parse(values[2])); - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[3]))); - - return position; - } - - private Position decodeStatus(DeviceSession deviceSession, String sentence) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(sentence.split(",")[0])); - - return position; - } - - private Position decodeNetwork(DeviceSession deviceSession, String sentence, boolean wifi) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - Network network = new Network(); - String[] fragments = sentence.split("\\|"); - - if (wifi) { - for (String item : fragments[0].split("_")) { - String[] values = item.split(","); - network.addWifiAccessPoint(WifiAccessPoint.from(values[0], Integer.parseInt(values[1]))); - } - } - - for (String item : fragments[wifi ? 1 : 0].split(":")) { - String[] values = item.split(","); - int lac = Integer.parseInt(values[0]); - int mnc = Integer.parseInt(values[1]); - int mcc = Integer.parseInt(values[2]); - int cid = Integer.parseInt(values[3]); - int rssi = Integer.parseInt(values[4]); - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); - } - - position.setNetwork(network); - - return position; - } - - private List<Position> decodeMessage( - Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - String imei = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { - return null; - } - - String version = parser.next(); - int type = parser.nextInt(); - - List<Position> positions = new LinkedList<>(); - String data = parser.next(); - - switch (type) { - case 90: - sendResponse(channel, imei, version, type, getServer(channel, ',')); - break; - case 91: - String time = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); - sendResponse(channel, imei, version, type, time + "|" + getServer(channel, ',')); - break; - case 1: - positions.add(decodeStatus(deviceSession, data)); - sendResponse(channel, imei, version, type, data.split(",")[1]); - break; - case 2: - for (String fragment : data.split("\\|")) { - positions.add(decodePosition(deviceSession, fragment)); - } - break; - case 3: - case 4: - positions.add(decodeNetwork(deviceSession, data, type == 3)); - break; - case 64: - sendResponse(channel, imei, version, type, data); - break; - default: - break; - } - - return positions.isEmpty() ? null : positions; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - buf.skipBytes(3); // header - buf.readUnsignedShort(); // length - - String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 3, StandardCharsets.US_ASCII); - - buf.skipBytes(3); // footer - - return decodeMessage(channel, remoteAddress, sentence); - } - -} diff --git a/src/org/traccar/protocol/XexunFrameDecoder.java b/src/org/traccar/protocol/XexunFrameDecoder.java deleted file mode 100644 index 114e94061..000000000 --- a/src/org/traccar/protocol/XexunFrameDecoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.protocol; - -import org.traccar.BaseFrameDecoder; -import org.traccar.helper.BufferUtil; - -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, ByteBuf buf) throws Exception { - - if (buf.readableBytes() < 80) { - return null; - } - - int beginIndex = BufferUtil.indexOf("GPRMC", buf); - if (beginIndex == -1) { - beginIndex = BufferUtil.indexOf("GNRMC", buf); - if (beginIndex == -1) { - return null; - } - } - - int identifierIndex = BufferUtil.indexOf("imei:", buf, beginIndex, buf.writerIndex()); - if (identifierIndex == -1) { - return null; - } - - int endIndex = buf.indexOf(identifierIndex, buf.writerIndex(), (byte) ','); - if (endIndex == -1) { - return null; - } - - buf.skipBytes(beginIndex - buf.readerIndex()); - - return buf.readRetainedSlice(endIndex - beginIndex + 1); - } - -} diff --git a/src/org/traccar/protocol/XexunProtocol.java b/src/org/traccar/protocol/XexunProtocol.java deleted file mode 100644 index 0005270fb..000000000 --- a/src/org/traccar/protocol/XexunProtocol.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - * 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.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; - -public class XexunProtocol extends BaseProtocol { - - public XexunProtocol() { - setSupportedDataCommands( - Command.TYPE_ENGINE_STOP, - Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - boolean full = Context.getConfig().getBoolean(getName() + ".extended"); - if (full) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); // tracker bug \n\r - } else { - pipeline.addLast(new XexunFrameDecoder()); - } - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XexunProtocolEncoder()); - pipeline.addLast(new XexunProtocolDecoder(XexunProtocol.this, full)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java deleted file mode 100644 index 5e2d0c05e..000000000 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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.util.regex.Pattern; - -public class XexunProtocolDecoder extends BaseProtocolDecoder { - - private final boolean full; - - public XexunProtocolDecoder(Protocol protocol, boolean full) { - super(protocol); - this.full = full; - } - - private static final Pattern PATTERN_BASIC = new PatternBuilder() - .expression("G[PN]RMC,") - .number("(?:(dd)(dd)(dd))?.?d*,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(d*?)(d?d.d+),([NS]),") // latitude - .number("(d*?)(d?d.d+),([EW])?,") // longitude - .number("(d+.?d*),") // speed - .number("(d+.?d*)?,") // course - .number("(?:(dd)(dd)(dd))?,") // date (ddmmyy) - .expression("[^*]*").text("*") - .number("xx") // checksum - .expression("\\r\\n").optional() - .expression(",([FL]),") // signal - .expression("([^,]*),").optional() // alarm - .any() - .number("imei:(d+),") // imei - .compile(); - - private static final Pattern PATTERN_FULL = new PatternBuilder() - .any() - .number("(d+),") // serial - .expression("([^,]+)?,") // phone number - .expression(PATTERN_BASIC.pattern()) - .number("(d+),") // satellites - .number("(-?d+.d+)?,") // altitude - .number("[FL]:(d+.d+)V") // power - .any() - .compile(); - - private String decodeStatus(Position position, String value) { - if (value != null) { - switch (value.toLowerCase()) { - case "acc on": - case "accstart": - position.set(Position.KEY_IGNITION, true); - break; - case "acc off": - case "accstop": - position.set(Position.KEY_IGNITION, false); - break; - case "help me!": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "low battery": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "move!": - case "moved!": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - default: - break; - } - } - return null; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Pattern pattern = PATTERN_BASIC; - if (full) { - pattern = PATTERN_FULL; - } - - Parser parser = new Parser(pattern, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - if (full) { - position.set("serial", parser.next()); - position.set("number", parser.next()); - } - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.setSpeed(convertSpeed(parser.nextDouble(0), "kn")); - - position.setCourse(parser.nextDouble(0)); - - dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setTime(dateBuilder.getDate()); - - position.set("signal", parser.next()); - - decodeStatus(position, parser.next()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - if (full) { - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_POWER, parser.nextDouble(0)); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/XexunProtocolEncoder.java b/src/org/traccar/protocol/XexunProtocolEncoder.java deleted file mode 100644 index 515cfbbd0..000000000 --- a/src/org/traccar/protocol/XexunProtocolEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@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.model.Command; - -public class XexunProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - initDevicePassword(command, "123456"); - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "powercar{%s} 11", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "powercar{%s} 00", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/XirgoProtocol.java b/src/org/traccar/protocol/XirgoProtocol.java deleted file mode 100644 index 4979fda5d..000000000 --- a/src/org/traccar/protocol/XirgoProtocol.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * 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.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; - -public class XirgoProtocol extends BaseProtocol { - - public XirgoProtocol() { - setSupportedDataCommands( - Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XirgoProtocolEncoder()); - pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); - } - }); - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XirgoProtocolEncoder()); - pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java deleted file mode 100644 index 6d215e672..000000000 --- a/src/org/traccar/protocol/XirgoProtocolDecoder.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2015 - 2019 Anton Tananaev (anton@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.Protocol; -import org.traccar.helper.DateBuilder; -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 XirgoProtocolDecoder extends BaseProtocolDecoder { - - private Boolean newFormat; - private String form; - - public XirgoProtocolDecoder(Protocol protocol) { - super(protocol); - form = Context.getConfig().getString(getProtocolName() + ".form"); - } - - public void setForm(String form) { - this.form = form; - } - - private static final Pattern PATTERN_OLD = new PatternBuilder() - .text("$$") - .number("(d+),") // imei - .number("(d+),") // event - .number("(dddd)/(dd)/(dd),") // date (yyyy/mm/dd) - .number("(dd):(dd):(dd),") // time (hh:mm:ss) - .number("(-?d+.?d*),") // latitude - .number("(-?d+.?d*),") // longitude - .number("(-?d+.?d*),") // altitude - .number("(d+.?d*),") // speed - .number("(d+.?d*),") // course - .number("(d+),") // satellites - .number("(d+.?d*),") // hdop - .number("(d+.d+),") // battery - .number("(d+),") // gsm - .number("(d+.?d*),") // odometer - .number("(d+),") // gps - .any() - .compile(); - - private static final Pattern PATTERN_NEW = new PatternBuilder() - .text("$$") - .number("(d+),") // imei - .number("(d+),") // event - .number("(dddd)/(dd)/(dd),") // date (yyyy/mm/dd) - .number("(dd):(dd):(dd),") // time (hh:mm:ss) - .number("(-?d+.?d*),") // latitude - .number("(-?d+.?d*),") // longitude - .number("(-?d+.?d*),") // altitude - .number("(d+.?d*),") // speed - .number("d+.?d*,") // acceleration - .number("d+.?d*,") // deceleration - .number("d+,") - .number("(d+.?d*),") // course - .number("(d+),") // satellites - .number("(d+.?d*),") // hdop - .number("(d+.?d*),") // odometer - .number("(d+.?d*),") // fuel consumption - .number("(d+.d+),") // battery - .number("(d+),") // gsm - .number("(d+),") // gps - .groupBegin() - .number("d,") // reset mode - .expression("([01])") // input 1 - .expression("([01])") // input 1 - .expression("([01])") // input 1 - .expression("([01]),") // output 1 - .number("(d+.?d*),") // adc 1 - .number("(d+.?d*),") // fuel level - .number("d+,") // engine load - .number("(d+),") // engine hours - .number("(d+),") // oil pressure - .number("(d+),") // oil level - .number("(-?d+),") // oil temperature - .number("(d+),") // coolant pressure - .number("(d+),") // coolant level - .number("(-?d+)") // coolant temperature - .groupEnd("?") - .any() - .compile(); - - private void decodeEvent(Position position, int event) { - - position.set(Position.KEY_EVENT, event); - - switch (event) { - case 4001: - case 4003: - case 6011: - case 6013: - position.set(Position.KEY_IGNITION, true); - break; - case 4002: - case 4004: - case 6012: - case 6014: - position.set(Position.KEY_IGNITION, false); - break; - case 4005: - position.set(Position.KEY_CHARGE, false); - break; - case 6002: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 6006: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 6007: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 6008: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 6009: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 6010: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case 6016: - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case 6017: - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case 6030: - case 6071: - position.set(Position.KEY_MOTION, true); - break; - case 6031: - position.set(Position.KEY_MOTION, false); - break; - case 6032: - position.set(Position.KEY_ALARM, Position.ALARM_PARKING); - break; - case 6090: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - case 6091: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - default: - break; - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - if (form != null) { - return decodeCustom(channel, remoteAddress, sentence); - } else { - return decodeFixed(channel, remoteAddress, sentence); - } - } - - - private Object decodeCustom( - Channel channel, SocketAddress remoteAddress, String sentence) { - - String[] keys = form.split(","); - String[] values = sentence.replace("$$", "").replace("##", "").split(","); - - Position position = new Position(getProtocolName()); - DateBuilder dateBuilder = new DateBuilder(); - - for (int i = 0; i < Math.min(keys.length, values.length); i++) { - switch (keys[i]) { - case "UID": - case "IM": - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); - if (deviceSession != null) { - position.setDeviceId(deviceSession.getDeviceId()); - } - break; - case "EV": - decodeEvent(position, Integer.parseInt(values[i])); - break; - case "D": - String[] date = values[i].split("/"); - dateBuilder.setMonth(Integer.parseInt(date[0])); - dateBuilder.setDay(Integer.parseInt(date[1])); - dateBuilder.setYear(Integer.parseInt(date[2])); - break; - case "T": - String[] time = values[i].split(":"); - dateBuilder.setHour(Integer.parseInt(time[0])); - dateBuilder.setMinute(Integer.parseInt(time[1])); - dateBuilder.setSecond(Integer.parseInt(time[2])); - break; - case "LT": - position.setLatitude(Double.parseDouble(values[i])); - break; - case "LN": - position.setLongitude(Double.parseDouble(values[i])); - break; - case "AL": - position.setAltitude(Integer.parseInt(values[i])); - break; - case "GSPT": - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[i]))); - break; - case "HD": - if (values[i].contains(".")) { - position.setCourse(Double.parseDouble(values[i])); - } else { - position.setCourse(Integer.parseInt(values[i]) * 0.1); - } - break; - case "SV": - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - case "BV": - position.set(Position.KEY_BATTERY, Double.parseDouble(values[i])); - break; - case "CQ": - position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); - break; - case "MI": - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[i])); - break; - case "GS": - position.setValid(Integer.parseInt(values[i]) == 3); - break; - case "SI": - position.set("iccid", values[i]); - break; - case "IG": - int ignition = Integer.parseInt(values[i]); - if (ignition > 0) { - position.set(Position.KEY_IGNITION, ignition == 1); - } - break; - case "OT": - position.set(Position.KEY_OUTPUT, Integer.parseInt(values[i])); - break; - default: - break; - } - } - - position.setTime(dateBuilder.getDate()); - - return position.getDeviceId() > 0 ? position : null; - } - - private Object decodeFixed( - Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser; - if (newFormat == null) { - parser = new Parser(PATTERN_NEW, sentence); - if (parser.matches()) { - newFormat = true; - } else { - parser = new Parser(PATTERN_OLD, sentence); - if (parser.matches()) { - newFormat = false; - } else { - return null; - } - } - } else { - if (newFormat) { - parser = new Parser(PATTERN_NEW, sentence); - } else { - parser = new Parser(PATTERN_OLD, sentence); - } - if (!parser.matches()) { - return null; - } - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - decodeEvent(position, parser.nextInt()); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - - if (newFormat) { - position.set(Position.KEY_ODOMETER, UnitsConverter.metersFromMiles(parser.nextDouble(0))); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); - } - - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_RSSI, parser.nextDouble()); - - if (!newFormat) { - position.set(Position.KEY_ODOMETER, UnitsConverter.metersFromMiles(parser.nextDouble(0))); - } - - position.setValid(parser.nextInt(0) == 1); - - if (newFormat && parser.hasNext(13)) { - position.set(Position.PREFIX_IN + 1, parser.nextInt()); - position.set(Position.PREFIX_IN + 2, parser.nextInt()); - position.set(Position.PREFIX_IN + 3, parser.nextInt()); - 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, UnitsConverter.msFromHours(parser.nextInt())); - position.set("oilPressure", parser.nextInt()); - position.set("oilLevel", parser.nextInt()); - position.set("oilTemp", parser.nextInt()); - position.set("coolantPressure", parser.nextInt()); - position.set("coolantLevel", parser.nextInt()); - position.set("coolantTemp", parser.nextInt()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/XirgoProtocolEncoder.java b/src/org/traccar/protocol/XirgoProtocolEncoder.java deleted file mode 100644 index dd5e30cca..000000000 --- a/src/org/traccar/protocol/XirgoProtocolEncoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.protocol; - -import org.traccar.StringProtocolEncoder; -import org.traccar.model.Command; - -public class XirgoProtocolEncoder extends StringProtocolEncoder { - - @Override - protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_OUTPUT_CONTROL: - return String.format("+XT:7005,%d,1", command.getInteger(Command.KEY_DATA) + 1); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Xrb28Protocol.java b/src/org/traccar/protocol/Xrb28Protocol.java deleted file mode 100644 index b1f1c34fb..000000000 --- a/src/org/traccar/protocol/Xrb28Protocol.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.nio.charset.StandardCharsets; - -public class Xrb28Protocol extends BaseProtocol { - - public Xrb28Protocol() { - setSupportedDataCommands( - Command.TYPE_CUSTOM, - Command.TYPE_POSITION_SINGLE, - Command.TYPE_POSITION_PERIODIC, - Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Xrb28ProtocolEncoder()); - pipeline.addLast(new Xrb28ProtocolDecoder(Xrb28Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/org/traccar/protocol/Xrb28ProtocolDecoder.java deleted file mode 100644 index 938394d6b..000000000 --- a/src/org/traccar/protocol/Xrb28ProtocolDecoder.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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.Protocol; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Command; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.regex.Pattern; - -public class Xrb28ProtocolDecoder extends BaseProtocolDecoder { - - private String pendingCommand; - - public void setPendingCommand(String pendingCommand) { - this.pendingCommand = pendingCommand; - } - - public Xrb28ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .text("*") - .expression("....,") - .expression("..,") // vendor - .number("d{15},") // imei - .expression("..,") // type - .number("0,") // reserved - .number("(dd)(dd)(dd).d+,") // time (hhmmss) - .expression("([AV]),") // validity - .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") - .number("(d{2,3})(dd.d+),") // longitude - .expression("([EW]),") - .number("(d+),") // satellites - .number("(d+.d+),") // hdop - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(-?d+.?d*),") // altitude - .expression(".,") // height unit - .expression(".#") // mode - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(9, 24)); - if (deviceSession == null) { - return null; - } - - String type = sentence.substring(25, 27); - if (channel != null) { - if (type.matches("L0|L1|W0|E1")) { - channel.write(new NetworkMessage( - "\u00ff\u00ff*SCOS" + sentence.substring(5, 27) + "#\n", - remoteAddress)); - } else if (type.equals("R0") && pendingCommand != null) { - String command = pendingCommand.equals(Command.TYPE_ALARM_ARM) ? "L1," : "L0,"; - channel.write(new NetworkMessage( - "\u00ff\u00ff*SCOS" + sentence.substring(5, 25) + command + sentence.substring(30) + "\n", - remoteAddress)); - pendingCommand = null; - } - } - - if (!type.startsWith("D")) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - String payload = sentence.substring(25, sentence.length() - 1); - - int index = 0; - String[] values = payload.substring(3).split(","); - - switch (type) { - case "Q0": - position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.01); - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); - position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); - break; - case "H0": - position.set(Position.KEY_BLOCKED, Integer.parseInt(values[index++]) > 0); - position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.01); - position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); - break; - case "W0": - switch (Integer.parseInt(values[index++])) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - default: - break; - } - break; - case "E0": - position.set(Position.KEY_ALARM, Position.ALARM_FAULT); - position.set("error", Integer.parseInt(values[index++])); - break; - case "S1": - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); - break; - case "R0": - case "L0": - case "L1": - case "S4": - case "S5": - case "S6": - case "S7": - case "V0": - case "G0": - case "K0": - case "I0": - case "M0": - position.set(Position.KEY_RESULT, payload); - break; - default: - break; - } - - return !position.getAttributes().isEmpty() ? position : null; - - } else { - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - DateBuilder dateBuilder = new DateBuilder() - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - - dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - position.setAltitude(parser.nextDouble()); - - return position; - - } - } - -} diff --git a/src/org/traccar/protocol/Xrb28ProtocolEncoder.java b/src/org/traccar/protocol/Xrb28ProtocolEncoder.java deleted file mode 100644 index 617639312..000000000 --- a/src/org/traccar/protocol/Xrb28ProtocolEncoder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.BaseProtocolEncoder; -import org.traccar.model.Command; - -public class Xrb28ProtocolEncoder extends BaseProtocolEncoder { - - private String formatCommand(Command command, String content) { - return String.format("\u00ff\u00ff*SCOS,OM,%s,%s#\n", getUniqueId(command.getDeviceId()), content); - } - - @Override - protected Object encodeCommand(Channel channel, Command command) { - - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "D0"); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "D1," + command.getInteger(Command.KEY_FREQUENCY)); - case Command.TYPE_ENGINE_STOP: - case Command.TYPE_ALARM_DISARM: - if (channel != null) { - Xrb28ProtocolDecoder decoder = channel.pipeline().get(Xrb28ProtocolDecoder.class); - if (decoder != null) { - decoder.setPendingCommand(command.getType()); - } - } - return formatCommand(command, "R0,0,20,1234," + System.currentTimeMillis() / 1000); - default: - return null; - } - } - -} diff --git a/src/org/traccar/protocol/Xt013Protocol.java b/src/org/traccar/protocol/Xt013Protocol.java deleted file mode 100644 index ebb3c123f..000000000 --- a/src/org/traccar/protocol/Xt013Protocol.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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 io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - -public class Xt013Protocol extends BaseProtocol { - - public Xt013Protocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Xt013ProtocolDecoder(Xt013Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/org/traccar/protocol/Xt013ProtocolDecoder.java deleted file mode 100644 index f49fb9563..000000000 --- a/src/org/traccar/protocol/Xt013ProtocolDecoder.java +++ /dev/null @@ -1,94 +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.protocol; - -import io.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -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 Xt013ProtocolDecoder extends BaseProtocolDecoder { - - public Xt013ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("HI,d+").optional() - .text("TK,") - .number("(d+),") // imei - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("([+-]d+.d+),") // latitude - .number("([+-]d+.d+),") // longitude - .number("(d+),") // speed - .number("(d+),") // course - .number("d+,") - .number("(d+),") // altitude - .expression("([FL]),") // gps fix - .number("d+,") - .number("(d+),") // gps level - .number("x+,") - .number("x+,") - .number("(d+),") // gsm level - .expression("[^,]*,") - .number("(d+.d+),") // battery - .number("(d),") // charging - .any() - .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; - } - - Position position = new Position(getProtocolName()); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - position.setValid(parser.next().equals("F")); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.set(Position.KEY_RSSI, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_CHARGE, parser.next().equals("1")); - - return position; - } - -} diff --git a/src/org/traccar/protocol/Xt2400Protocol.java b/src/org/traccar/protocol/Xt2400Protocol.java deleted file mode 100644 index 9427876c8..000000000 --- a/src/org/traccar/protocol/Xt2400Protocol.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * 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; - -public class Xt2400Protocol extends BaseProtocol { - - public Xt2400Protocol() { - addServer(new TrackerServer(true, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java deleted file mode 100644 index 819011a50..000000000 --- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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. - * 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 org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.Protocol; -import org.traccar.helper.DataConverter; -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.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { - - public Xt2400ProtocolDecoder(Protocol protocol) { - super(protocol); - - String config = Context.getConfig().getString(getProtocolName() + ".config"); - if (config != null) { - setConfig(config); - } - } - - private static final Map<Integer, Integer> TAG_LENGTH_MAP = new HashMap<>(); - - static { - int[] l1 = { - 0x01, 0x02, 0x04, 0x0b, 0x0c, 0x0d, 0x12, 0x13, - 0x16, 0x17, 0x1c, 0x1f, 0x23, 0x2c, 0x2d, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x40, 0x41, - 0x53, 0x66, 0x69, 0x6a, 0x93, 0x94, 0x96 - }; - int[] l2 = { - 0x05, 0x09, 0x0a, 0x14, 0x15, 0x1d, 0x1e, 0x24, - 0x26, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x57, 0x58, 0x59, 0x5a, 0x6b, 0x6f, 0x7A, - 0x7B, 0x7C, 0x7d, 0x7E, 0x7F, 0x80, 0x81, 0x82, - 0x83, 0x84, 0x85, 0x86 - }; - int[] l4 = { - 0x03, 0x06, 0x07, 0x08, 0x0e, 0x0f, 0x10, 0x11, - 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22, 0x2e, - 0x2f, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0x54, 0x55, 0x56, 0x5b, 0x5c, 0x5d, - 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x68, 0x6e, 0x71, - 0x72, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d - }; - for (int i : l1) { - TAG_LENGTH_MAP.put(i, 1); - } - for (int i : l2) { - TAG_LENGTH_MAP.put(i, 2); - } - for (int i : l4) { - TAG_LENGTH_MAP.put(i, 4); - } - TAG_LENGTH_MAP.put(0x95, 24); - } - - private static int getTagLength(int tag) { - Integer length = TAG_LENGTH_MAP.get(tag); - if (length == null) { - throw new IllegalArgumentException("Unknown tag: " + tag); - } - return length; - } - - private Map<Short, byte[]> formats = new HashMap<>(); - - public void setConfig(String configString) { - Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)"); - Matcher matcher = pattern.matcher(configString); - while (matcher.find()) { - formats.put(Short.parseShort(matcher.group(1), 16), DataConverter.parseHex(matcher.group(2))); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ByteBuf buf = (ByteBuf) msg; - - byte[] format = null; - if (formats.size() > 1) { - format = formats.get(buf.getUnsignedByte(buf.readerIndex())); - } else if (!formats.isEmpty()) { - format = formats.values().iterator().next(); - } - - if (format == null) { - return null; - } - - Position position = new Position(getProtocolName()); - - for (byte tag : format) { - switch (tag) { - case 0x03: - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - break; - case 0x04: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - break; - case 0x05: - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); - break; - case 0x06: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - break; - case 0x07: - position.setLatitude(buf.readInt() * 0.000001); - break; - case 0x08: - position.setLongitude(buf.readInt() * 0.000001); - break; - case 0x09: - position.setAltitude(buf.readShort() * 0.1); - break; - case 0x0a: - position.setCourse(buf.readShort() * 0.1); - break; - case 0x0b: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - break; - case 0x10: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); - break; - case 0x12: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x13: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x14: - position.set(Position.KEY_RSSI, buf.readShort()); - break; - case 0x16: - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); - break; - case 0x17: - position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); - break; - case 0x57: - position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(buf.readUnsignedShort())); - break; - case 0x65: - position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); - break; - case 0x73: - position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); - break; - default: - buf.skipBytes(getTagLength(tag)); - break; - } - } - - if (position.getLatitude() != 0 && position.getLongitude() != 0) { - position.setValid(true); - } else { - getLastLocation(position, position.getDeviceTime()); - } - - return position; - } - -} diff --git a/src/org/traccar/protocol/YwtProtocol.java b/src/org/traccar/protocol/YwtProtocol.java deleted file mode 100644 index c525b75cf..000000000 --- a/src/org/traccar/protocol/YwtProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * 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; - -public class YwtProtocol extends BaseProtocol { - - public YwtProtocol() { - addServer(new TrackerServer(false, getName()) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); - pipeline.addLast(new StringEncoder()); - pipeline.addLast(new StringDecoder()); - pipeline.addLast(new YwtProtocolDecoder(YwtProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/YwtProtocolDecoder.java b/src/org/traccar/protocol/YwtProtocolDecoder.java deleted file mode 100644 index bf5a23fa7..000000000 --- a/src/org/traccar/protocol/YwtProtocolDecoder.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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. - * 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.Protocol; -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 YwtProtocolDecoder extends BaseProtocolDecoder { - - public YwtProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .expression("%(..),") // type - .number("(d+):") // unit identifier - .number("d+,") // subtype - .number("(dd)(dd)(dd)") // date (yymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([EW])") - .number("(ddd.d{6}),") // longitude - .expression("([NS])") - .number("(dd.d{6}),") // latitude - .number("(d+)?,") // altitude - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // satellite - .expression("([^,]+),") // report identifier - .expression("([-0-9a-fA-F]+)") // status - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - // Synchronization - if (sentence.startsWith("%SN") && channel != null) { - int start = sentence.indexOf(':'); - int end = start; - for (int i = 0; i < 4; i++) { - end = sentence.indexOf(',', end + 1); - } - if (end == -1) { - end = sentence.length(); - } - - channel.writeAndFlush(new NetworkMessage("%AT+SN=" + sentence.substring(start, end), remoteAddress)); - return null; - } - - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - - String type = parser.next(); - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime()); - - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setAltitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - - int satellites = parser.nextInt(); - position.setValid(satellites != 0); - position.set(Position.KEY_SATELLITES, satellites); - - String reportId = parser.next(); - - position.set(Position.KEY_STATUS, parser.next()); - - // Send response - if ((type.equals("KP") || type.equals("EP")) && channel != null) { - 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 deleted file mode 100644 index 66d9e708d..000000000 --- a/src/org/traccar/reports/Events.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - * 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -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 { - - private Events() { - } - - public static Collection<Event> getObjects(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Collection<String> types, Date from, Date to) throws SQLException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<Event> result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection<Event> events = Context.getDataManager().getEvents(deviceId, from, to); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Event event : events) { - if (all || types.contains(event.getType())) { - long geofenceId = event.getGeofenceId(); - long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) - && (maintenanceId == 0 - || Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId))) { - result.add(event); - } - } - } - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Collection<String> types, Date from, Date to) throws SQLException, IOException { - ReportUtils.checkPeriodLimit(from, to); - 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); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Iterator<Event> iterator = events.iterator(); iterator.hasNext();) { - 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); - if (geofence != null) { - geofenceNames.put(geofenceId, geofence.getName()); - } - } 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(); - } - } - DeviceReport deviceEvents = new DeviceReport(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceEvents.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceEvents.setGroupName(group.getName()); - } - } - deviceEvents.setObjects(events); - devicesEvents.add(deviceEvents); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - 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 deleted file mode 100644 index 3a631e0d9..000000000 --- a/src/org/traccar/reports/ReportUtils.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * 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"); - * 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.reports; - -import org.apache.velocity.tools.generic.DateTool; -import org.apache.velocity.tools.generic.NumberTool; -import org.jxls.area.Area; -import org.jxls.builder.xls.XlsCommentAreaBuilder; -import org.jxls.common.CellRef; -import org.jxls.formula.StandardFormulaProcessor; -import org.jxls.transform.Transformer; -import org.jxls.transform.poi.PoiTransformer; -import org.jxls.util.TransformerFactory; -import org.traccar.Context; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.model.DeviceState; -import org.traccar.model.Driver; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -public final class ReportUtils { - - private ReportUtils() { - } - - public static void checkPeriodLimit(Date from, Date to) { - long limit = Context.getConfig().getLong("report.periodLimit") * 1000; - if (limit > 0 && to.getTime() - from.getTime() > limit) { - throw new IllegalArgumentException("Time period exceeds the limit"); - } - } - - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - public static Collection<Long> getDeviceList(Collection<Long> deviceIds, Collection<Long> groupIds) { - Collection<Long> result = new ArrayList<>(); - result.addAll(deviceIds); - for (long groupId : groupIds) { - result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); - } - return result; - } - - public static double calculateDistance(Position firstPosition, Position lastPosition) { - return calculateDistance(firstPosition, lastPosition, true); - } - - public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { - double distance = 0.0; - double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); - double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); - - if (useOdometer && (firstOdometer != 0.0 || lastOdometer != 0.0)) { - distance = lastOdometer - firstOdometer; - } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) - && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { - distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) - - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); - } - return distance; - } - - public static double calculateFuel(Position firstPosition, Position lastPosition) { - - if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null - && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { - - BigDecimal value = new BigDecimal(firstPosition.getDouble(Position.KEY_FUEL_LEVEL) - - lastPosition.getDouble(Position.KEY_FUEL_LEVEL)); - return value.setScale(1, RoundingMode.HALF_EVEN).doubleValue(); - } - return 0; - } - - public static String findDriver(Position firstPosition, Position lastPosition) { - if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } - return null; - } - - public static String findDriverName(String driverUniqueId) { - if (driverUniqueId != null && Context.getDriversManager() != null) { - Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); - if (driver != null) { - return driver.getName(); - } - } - return null; - } - - public static org.jxls.common.Context initializeContext(long userId) { - org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); - jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); - jxlsContext.putVar("dateTool", new DateTool()); - jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); - jxlsContext.putVar("locale", Locale.getDefault()); - jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); - return jxlsContext; - } - - 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) { - xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); - xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); - xlsArea.processFormulas(); - } - transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName()); - transformer.write(); - } - - private static TripReport calculateTrip( - ArrayList<Position> positions, int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startTrip = positions.get(startIndex); - Position endTrip = positions.get(endIndex); - - double speedMax = 0.0; - double speedSum = 0.0; - for (int i = startIndex; i <= endIndex; i++) { - double speed = positions.get(i).getSpeed(); - speedSum += speed; - if (speed > speedMax) { - speedMax = speed; - } - } - - TripReport trip = new TripReport(); - - long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); - long deviceId = startTrip.getDeviceId(); - trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); - - trip.setStartPositionId(startTrip.getId()); - trip.setStartLat(startTrip.getLatitude()); - trip.setStartLon(startTrip.getLongitude()); - trip.setStartTime(startTrip.getFixTime()); - String startAddress = startTrip.getAddress(); - if (startAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean("geocoder.onRequest")) { - startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); - } - trip.setStartAddress(startAddress); - - trip.setEndPositionId(endTrip.getId()); - trip.setEndLat(endTrip.getLatitude()); - trip.setEndLon(endTrip.getLongitude()); - trip.setEndTime(endTrip.getFixTime()); - String endAddress = endTrip.getAddress(); - if (endAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean("geocoder.onRequest")) { - endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); - } - trip.setEndAddress(endAddress); - - trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); - trip.setDuration(tripDuration); - trip.setAverageSpeed(speedSum / (endIndex - startIndex)); - trip.setMaxSpeed(speedMax); - trip.setSpentFuel(calculateFuel(startTrip, endTrip)); - - 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, boolean ignoreOdometer) { - - Position startStop = positions.get(startIndex); - Position endStop = positions.get(endIndex); - - StopReport stop = new StopReport(); - - long deviceId = startStop.getDeviceId(); - stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); - - stop.setPositionId(startStop.getId()); - stop.setLatitude(startStop.getLatitude()); - stop.setLongitude(startStop.getLongitude()); - stop.setStartTime(startStop.getFixTime()); - String address = startStop.getAddress(); - if (address == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean("geocoder.onRequest")) { - address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); - } - stop.setAddress(address); - - stop.setEndTime(endStop.getFixTime()); - - long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime(); - stop.setDuration(stopDuration); - stop.setSpentFuel(calculateFuel(startStop, endStop)); - - long engineHours = 0; - 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) { - - if (reportClass.equals(TripReport.class)) { - return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); - } else { - return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); - } - } - - private static boolean isMoving(ArrayList<Position> positions, int index, TripsConfig tripsConfig) { - if (tripsConfig.getMinimalNoDataDuration() > 0) { - boolean beforeGap = index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - boolean afterGap = index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - if (beforeGap || afterGap) { - return false; - } - } - if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) - && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { - return positions.get(index).getBoolean(Position.KEY_MOTION); - } else { - return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); - } - } - - public static <T extends BaseReport> Collection<T> detectTripsAndStops( - IdentityManager identityManager, DeviceManager deviceManager, - Collection<Position> positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class<T> reportClass) { - - Collection<T> result = new ArrayList<>(); - - ArrayList<Position> positions = new ArrayList<>(positionCollection); - if (!positions.isEmpty()) { - boolean trips = reportClass.equals(TripReport.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); - int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; - int startNoEventIndex = -1; - for (int i = 0; i < positions.size(); i++) { - Map<Event, Position> event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig)); - if (startEventIndex == -1 - && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips == deviceState.getMotionState() && event != null)) { - startEventIndex = i; - startNoEventIndex = -1; - } else if (trips != deviceState.getMotionState() && startEventIndex != -1 - && deviceState.getMotionPosition() == null && event == null) { - startEventIndex = -1; - } - if (startNoEventIndex == -1 - && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips != deviceState.getMotionState() && event != null)) { - startNoEventIndex = i; - } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { - startNoEventIndex = -1; - } - if (startEventIndex != -1 && startNoEventIndex != -1 && event != null - && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(positions, startEventIndex, startNoEventIndex, - ignoreOdometer, reportClass)); - startEventIndex = -1; - } - } - if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(positions, startEventIndex, - startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); - } - } - - return result; - } - -} diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java deleted file mode 100644 index 6adb00aae..000000000 --- a/src/org/traccar/reports/Route.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Position; -import org.traccar.reports.model.DeviceReport; - -public final class Route { - - private Route() { - } - - public static Collection<Position> getObjects(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<Position> result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<DeviceReport> devicesRoutes = new ArrayList<>(); - ArrayList<String> sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection<Position> positions = Context.getDataManager() - .getPositions(deviceId, from, to); - DeviceReport deviceRoutes = new DeviceReport(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceRoutes.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceRoutes.setGroupName(group.getName()); - } - } - deviceRoutes.setObjects(positions); - devicesRoutes.add(deviceRoutes); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesRoutes); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java deleted file mode 100644 index 98c9cef00..000000000 --- a/src/org/traccar/reports/Stops.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.StopReport; - -public final class Stops { - - private Stops() { - } - - private static Collection<StopReport> detectStops(long deviceId, Date from, Date to) throws SQLException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReport.class); - } - - public static Collection<StopReport> getObjects( - long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<StopReport> result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectStops(deviceId, from, to)); - } - return result; - } - - public static void getExcel( - OutputStream outputStream, long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<DeviceReport> devicesStops = new ArrayList<>(); - ArrayList<String> sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection<StopReport> stops = detectStops(deviceId, from, to); - DeviceReport deviceStops = new DeviceReport(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceStops.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceStops.setGroupName(group.getName()); - } - } - deviceStops.setObjects(stops); - devicesStops.add(deviceStops); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesStops); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java deleted file mode 100644 index 9810424d8..000000000 --- a/src/org/traccar/reports/Summary.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.jxls.util.JxlsHelper; -import org.traccar.Context; -import org.traccar.model.Position; -import org.traccar.reports.model.SummaryReport; - -public final class Summary { - - private Summary() { - } - - private static SummaryReport calculateSummaryResult(long deviceId, Date from, Date to) throws SQLException { - SummaryReport result = new SummaryReport(); - result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); - Collection<Position> positions = Context.getDataManager().getPositions(deviceId, from, to); - if (positions != null && !positions.isEmpty()) { - 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 (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()); - } - previousPosition = position; - speedSum += position.getSpeed(); - result.setMaxSpeed(position.getSpeed()); - } - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - 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; - } - - public static Collection<SummaryReport> getObjects(long userId, Collection<Long> deviceIds, - Collection<Long> groupIds, Date from, Date to) throws SQLException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<SummaryReport> result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.add(calculateSummaryResult(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException, IOException { - ReportUtils.checkPeriodLimit(from, to); - Collection<SummaryReport> summaries = getObjects(userId, deviceIds, groupIds, from, to); - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("summaries", summaries); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - JxlsHelper.getInstance().setUseFastFormulaProcessor(false) - .processTemplate(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java deleted file mode 100644 index 3cda65553..000000000 --- a/src/org/traccar/reports/Trips.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.TripReport; - -public final class Trips { - - private Trips() { - } - - private static Collection<TripReport> detectTrips(long deviceId, Date from, Date to) throws SQLException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReport.class); - } - - public static Collection<TripReport> getObjects(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<TripReport> result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectTrips(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection<Long> deviceIds, Collection<Long> groupIds, - Date from, Date to) throws SQLException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList<DeviceReport> devicesTrips = new ArrayList<>(); - ArrayList<String> sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection<TripReport> trips = detectTrips(deviceId, from, to); - DeviceReport deviceTrips = new DeviceReport(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceTrips.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceTrips.setGroupName(group.getName()); - } - } - deviceTrips.setObjects(trips); - devicesTrips.add(deviceTrips); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesTrips); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/org/traccar/reports/model/BaseReport.java b/src/org/traccar/reports/model/BaseReport.java deleted file mode 100644 index 9f2d1188c..000000000 --- a/src/org/traccar/reports/model/BaseReport.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -public class BaseReport { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private double distance; - - public double getDistance() { - return distance; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public void addDistance(double distance) { - this.distance += distance; - } - - private double averageSpeed; - - public double getAverageSpeed() { - return averageSpeed; - } - - public void setAverageSpeed(Double averageSpeed) { - this.averageSpeed = averageSpeed; - } - - private double maxSpeed; - - public double getMaxSpeed() { - return maxSpeed; - } - - public void setMaxSpeed(double maxSpeed) { - if (maxSpeed > this.maxSpeed) { - this.maxSpeed = maxSpeed; - } - } - - private double spentFuel; - - public double getSpentFuel() { - return spentFuel; - } - - public void setSpentFuel(double spentFuel) { - 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/reports/model/DeviceReport.java b/src/org/traccar/reports/model/DeviceReport.java deleted file mode 100644 index 932753d15..000000000 --- a/src/org/traccar/reports/model/DeviceReport.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class DeviceReport { - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private String groupName = ""; - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - private List<?> objects; - - public Collection<?> getObjects() { - return objects; - } - - public void setObjects(Collection<?> objects) { - this.objects = new ArrayList<>(objects); - } - -} diff --git a/src/org/traccar/reports/model/StopReport.java b/src/org/traccar/reports/model/StopReport.java deleted file mode 100644 index 245292b63..000000000 --- a/src/org/traccar/reports/model/StopReport.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.reports.model; - -import java.util.Date; - -public class StopReport extends BaseReport { - - private long positionId; - - public long getPositionId() { - return positionId; - } - - public void setPositionId(long positionId) { - this.positionId = positionId; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private Date startTime; - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - private Date endTime; - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - private String address; - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } - - public void addEngineHours(long engineHours) { - this.engineHours += engineHours; - } -} diff --git a/src/org/traccar/reports/model/SummaryReport.java b/src/org/traccar/reports/model/SummaryReport.java deleted file mode 100644 index 6f9e9459f..000000000 --- a/src/org/traccar/reports/model/SummaryReport.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 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.reports.model; - -public class SummaryReport extends BaseReport { - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } - - public void addEngineHours(long engineHours) { - this.engineHours += engineHours; - } -} diff --git a/src/org/traccar/reports/model/TripReport.java b/src/org/traccar/reports/model/TripReport.java deleted file mode 100644 index 3140f3019..000000000 --- a/src/org/traccar/reports/model/TripReport.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.reports.model; - -import java.util.Date; - -public class TripReport extends BaseReport { - - private long startPositionId; - - public long getStartPositionId() { - return startPositionId; - } - - public void setStartPositionId(long startPositionId) { - this.startPositionId = startPositionId; - } - - private long endPositionId; - - public long getEndPositionId() { - return endPositionId; - } - - public void setEndPositionId(long endPositionId) { - this.endPositionId = endPositionId; - } - - private double startLat; - - public double getStartLat() { - return startLat; - } - - public void setStartLat(double startLat) { - this.startLat = startLat; - } - - private double startLon; - - public double getStartLon() { - return startLon; - } - - public void setStartLon(double startLon) { - this.startLon = startLon; - } - - private double endLat; - - public double getEndLat() { - return endLat; - } - - public void setEndLat(double endLat) { - this.endLat = endLat; - } - - private double endLon; - - public double getEndLon() { - return endLon; - } - - public void setEndLon(double endLon) { - this.endLon = endLon; - } - - private Date startTime; - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - private String startAddress; - - public String getStartAddress() { - return startAddress; - } - - public void setStartAddress(String address) { - this.startAddress = address; - } - - private Date endTime; - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - private String endAddress; - - public String getEndAddress() { - return endAddress; - } - - public void setEndAddress(String address) { - this.endAddress = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private String driverUniqueId; - - public String getDriverUniqueId() { - return driverUniqueId; - } - - public void setDriverUniqueId(String driverUniqueId) { - this.driverUniqueId = driverUniqueId; - } - - private String driverName; - - public String getDriverName() { - return driverName; - } - - public void setDriverName(String driverName) { - this.driverName = driverName; - } -} diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java deleted file mode 100644 index 0f0c615d3..000000000 --- a/src/org/traccar/reports/model/TripsConfig.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.reports.model; - -public class TripsConfig { - - public TripsConfig() { - } - - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { - this.minimalTripDistance = minimalTripDistance; - this.minimalTripDuration = minimalTripDuration; - this.minimalParkingDuration = minimalParkingDuration; - this.minimalNoDataDuration = minimalNoDataDuration; - this.useIgnition = useIgnition; - this.processInvalidPositions = processInvalidPositions; - this.speedThreshold = speedThreshold; - } - - private double minimalTripDistance; - - public double getMinimalTripDistance() { - return minimalTripDistance; - } - - public void setMinimalTripDistance(double minimalTripDistance) { - this.minimalTripDistance = minimalTripDistance; - } - - private long minimalTripDuration; - - public long getMinimalTripDuration() { - return minimalTripDuration; - } - - public void setMinimalTripDuration(long minimalTripDuration) { - this.minimalTripDuration = minimalTripDuration; - } - - private long minimalParkingDuration; - - public long getMinimalParkingDuration() { - return minimalParkingDuration; - } - - public void setMinimalParkingDuration(long minimalParkingDuration) { - this.minimalParkingDuration = minimalParkingDuration; - } - - private long minimalNoDataDuration; - - public long getMinimalNoDataDuration() { - return minimalNoDataDuration; - } - - public void setMinimalNoDataDuration(long minimalNoDataDuration) { - this.minimalNoDataDuration = minimalNoDataDuration; - } - - private boolean useIgnition; - - public boolean getUseIgnition() { - return useIgnition; - } - - public void setUseIgnition(boolean useIgnition) { - this.useIgnition = useIgnition; - } - - private boolean processInvalidPositions; - - public boolean getProcessInvalidPositions() { - return processInvalidPositions; - } - - public void setProcessInvalidPositions(boolean processInvalidPositions) { - this.processInvalidPositions = processInvalidPositions; - } - - private double speedThreshold; - - public double getSpeedThreshold() { - return speedThreshold; - } - - public void setSpeedThreshold(double speedThreshold) { - this.speedThreshold = speedThreshold; - } - -} diff --git a/src/org/traccar/sms/HttpSmsClient.java b/src/org/traccar/sms/HttpSmsClient.java deleted file mode 100644 index 8e2b67bf7..000000000 --- a/src/org/traccar/sms/HttpSmsClient.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.sms; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.api.SecurityRequestFilter; -import org.traccar.helper.DataConverter; -import org.traccar.notification.MessageException; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - -public class HttpSmsClient implements SmsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(HttpSmsClient.class); - - private String url; - private String authorizationHeader; - private String authorization; - private String template; - private boolean encode; - private MediaType mediaType; - - public HttpSmsClient() { - url = Context.getConfig().getString("sms.http.url"); - authorizationHeader = Context.getConfig().getString("sms.http.authorizationHeader", - SecurityRequestFilter.AUTHORIZATION_HEADER); - authorization = Context.getConfig().getString("sms.http.authorization"); - if (authorization == null) { - String user = Context.getConfig().getString("sms.http.user"); - String password = Context.getConfig().getString("sms.http.password"); - authorization = "Basic " - + DataConverter.printBase64((user + ":" + password).getBytes(StandardCharsets.UTF_8)); - } - template = Context.getConfig().getString("sms.http.template").trim(); - if (template.charAt(0) == '{' || template.charAt(0) == '[') { - encode = false; - mediaType = MediaType.APPLICATION_JSON_TYPE; - } else { - encode = true; - mediaType = MediaType.APPLICATION_FORM_URLENCODED_TYPE; - } - } - - private String prepareValue(String value) throws UnsupportedEncodingException { - return encode ? URLEncoder.encode(value, StandardCharsets.UTF_8.name()) : value; - } - - private String preparePayload(String destAddress, String message) { - try { - return template - .replace("{phone}", prepareValue(destAddress)) - .replace("{message}", prepareValue(message.trim())); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - private Invocation.Builder getRequestBuilder() { - return Context.getClient().target(url).request() - .header(authorizationHeader, authorization); - } - - @Override - public void sendMessageSync(String destAddress, String message, boolean command) throws MessageException { - Response response = getRequestBuilder().post(Entity.entity(preparePayload(destAddress, message), mediaType)); - if (response.getStatus() / 100 != 2) { - throw new MessageException(response.readEntity(String.class)); - } - } - - @Override - public void sendMessageAsync(final String destAddress, final String message, final boolean command) { - getRequestBuilder().async().post( - Entity.entity(preparePayload(destAddress, message), mediaType), new InvocationCallback<String>() { - @Override - public void completed(String s) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("SMS send failed", throwable); - } - }); - } - -} diff --git a/src/org/traccar/sms/SmsManager.java b/src/org/traccar/sms/SmsManager.java deleted file mode 100644 index 1e3d40f6e..000000000 --- a/src/org/traccar/sms/SmsManager.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.sms; - -import org.traccar.notification.MessageException; - -public interface SmsManager { - - void sendMessageSync( - String destAddress, String message, boolean command) throws InterruptedException, MessageException; - - void sendMessageAsync( - final String destAddress, final String message, final boolean command); - -} diff --git a/src/org/traccar/sms/smpp/ClientSmppSessionHandler.java b/src/org/traccar/sms/smpp/ClientSmppSessionHandler.java deleted file mode 100644 index 6b9de3107..000000000 --- a/src/org/traccar/sms/smpp/ClientSmppSessionHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.sms.smpp; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.cloudhopper.commons.charset.CharsetUtil; -import com.cloudhopper.smpp.SmppConstants; -import com.cloudhopper.smpp.impl.DefaultSmppSessionHandler; -import com.cloudhopper.smpp.pdu.DeliverSm; -import com.cloudhopper.smpp.pdu.PduRequest; -import com.cloudhopper.smpp.pdu.PduResponse; -import com.cloudhopper.smpp.util.SmppUtil; - -public class ClientSmppSessionHandler extends DefaultSmppSessionHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(ClientSmppSessionHandler.class); - - private SmppClient smppClient; - - public ClientSmppSessionHandler(SmppClient smppClient) { - this.smppClient = smppClient; - } - - @Override - public void firePduRequestExpired(PduRequest pduRequest) { - LOGGER.warn("PDU request expired: " + pduRequest); - } - - @Override - public PduResponse firePduRequestReceived(PduRequest request) { - PduResponse response; - try { - if (request instanceof DeliverSm) { - String sourceAddress = ((DeliverSm) request).getSourceAddress().getAddress(); - String message = CharsetUtil.decode(((DeliverSm) request).getShortMessage(), - smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())); - LOGGER.info("SMS Message Received: " + message.trim() + ", Source Address: " + sourceAddress); - - boolean isDeliveryReceipt; - if (smppClient.getDetectDlrByOpts()) { - isDeliveryReceipt = request.getOptionalParameters() != null; - } else { - isDeliveryReceipt = SmppUtil.isMessageTypeAnyDeliveryReceipt(((DeliverSm) request).getEsmClass()); - } - - if (!isDeliveryReceipt) { - TextMessageEventHandler.handleTextMessage(sourceAddress, message); - } - } - response = request.createResponse(); - } catch (Exception error) { - LOGGER.warn("SMS receiving error", error); - response = request.createResponse(); - response.setResultMessage(error.getMessage()); - response.setCommandStatus(SmppConstants.STATUS_UNKNOWNERR); - } - return response; - } - - @Override - public void fireChannelUnexpectedlyClosed() { - LOGGER.warn("SMPP session channel unexpectedly closed"); - smppClient.scheduleReconnect(); - } - -} diff --git a/src/org/traccar/sms/smpp/EnquireLinkTask.java b/src/org/traccar/sms/smpp/EnquireLinkTask.java deleted file mode 100644 index 7086709d7..000000000 --- a/src/org/traccar/sms/smpp/EnquireLinkTask.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.sms.smpp; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.cloudhopper.smpp.SmppSession; -import com.cloudhopper.smpp.pdu.EnquireLink; -import com.cloudhopper.smpp.type.RecoverablePduException; -import com.cloudhopper.smpp.type.SmppChannelException; -import com.cloudhopper.smpp.type.SmppTimeoutException; -import com.cloudhopper.smpp.type.UnrecoverablePduException; - -public class EnquireLinkTask implements Runnable { - - private static final Logger LOGGER = LoggerFactory.getLogger(EnquireLinkTask.class); - - private SmppClient smppClient; - private Integer enquireLinkTimeout; - - public EnquireLinkTask(SmppClient smppClient, Integer enquireLinkTimeout) { - this.smppClient = smppClient; - this.enquireLinkTimeout = enquireLinkTimeout; - } - - @Override - public void run() { - SmppSession smppSession = smppClient.getSession(); - if (smppSession != null && smppSession.isBound()) { - try { - smppSession.enquireLink(new EnquireLink(), enquireLinkTimeout); - } catch (SmppTimeoutException | SmppChannelException - | RecoverablePduException | UnrecoverablePduException error) { - LOGGER.warn("Enquire link failed, executing reconnect: ", error); - smppClient.scheduleReconnect(); - } catch (InterruptedException error) { - LOGGER.info("Enquire link interrupted, probably killed by reconnecting"); - } - } else { - LOGGER.warn("Enquire link running while session is not connected"); - } - } - -} diff --git a/src/org/traccar/sms/smpp/ReconnectionTask.java b/src/org/traccar/sms/smpp/ReconnectionTask.java deleted file mode 100644 index c009de8e7..000000000 --- a/src/org/traccar/sms/smpp/ReconnectionTask.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.sms.smpp; - -public class ReconnectionTask implements Runnable { - - private final SmppClient smppClient; - - protected ReconnectionTask(SmppClient smppClient) { - this.smppClient = smppClient; - } - - @Override - public void run() { - smppClient.reconnect(); - } - -} diff --git a/src/org/traccar/sms/smpp/SmppClient.java b/src/org/traccar/sms/smpp/SmppClient.java deleted file mode 100644 index 874253d36..000000000 --- a/src/org/traccar/sms/smpp/SmppClient.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2017 - 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. - * 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.sms.smpp; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.notification.MessageException; -import org.traccar.sms.SmsManager; - -import com.cloudhopper.commons.charset.CharsetUtil; -import com.cloudhopper.smpp.SmppBindType; -import com.cloudhopper.smpp.SmppConstants; -import com.cloudhopper.smpp.SmppSession; -import com.cloudhopper.smpp.SmppSessionConfiguration; -import com.cloudhopper.smpp.impl.DefaultSmppClient; -import com.cloudhopper.smpp.impl.DefaultSmppSessionHandler; -import com.cloudhopper.smpp.pdu.SubmitSm; -import com.cloudhopper.smpp.pdu.SubmitSmResp; -import com.cloudhopper.smpp.tlv.Tlv; -import com.cloudhopper.smpp.type.Address; -import com.cloudhopper.smpp.type.RecoverablePduException; -import com.cloudhopper.smpp.type.SmppChannelException; -import com.cloudhopper.smpp.type.SmppTimeoutException; -import com.cloudhopper.smpp.type.UnrecoverablePduException; - -public class SmppClient implements SmsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(SmppClient.class); - - private SmppSessionConfiguration sessionConfig = new SmppSessionConfiguration(); - private SmppSession smppSession; - private DefaultSmppSessionHandler sessionHandler = new ClientSmppSessionHandler(this); - private ExecutorService executorService = Executors.newCachedThreadPool(); - private DefaultSmppClient clientBootstrap = new DefaultSmppClient(); - - private ScheduledExecutorService enquireLinkExecutor; - private ScheduledFuture<?> enquireLinkTask; - private Integer enquireLinkPeriod; - private Integer enquireLinkTimeout; - - private ScheduledExecutorService reconnectionExecutor; - private ScheduledFuture<?> reconnectionTask; - private Integer reconnectionDelay; - - private String sourceAddress; - private String commandSourceAddress; - private int submitTimeout; - private boolean requestDlr; - private boolean detectDlrByOpts; - private String notificationsCharsetName; - private byte notificationsDataCoding; - private String commandsCharsetName; - private byte commandsDataCoding; - - private byte sourceTon; - private byte sourceNpi; - private byte commandSourceTon; - private byte commandSourceNpi; - - private byte destTon; - private byte destNpi; - - public SmppClient() { - sessionConfig.setName("Traccar.smppSession"); - sessionConfig.setInterfaceVersion( - (byte) Context.getConfig().getInteger("sms.smpp.version", SmppConstants.VERSION_3_4)); - sessionConfig.setType(SmppBindType.TRANSCEIVER); - sessionConfig.setHost(Context.getConfig().getString("sms.smpp.host", "localhost")); - sessionConfig.setPort(Context.getConfig().getInteger("sms.smpp.port", 2775)); - sessionConfig.setSystemId(Context.getConfig().getString("sms.smpp.username", "user")); - sessionConfig.setSystemType(Context.getConfig().getString("sms.smpp.systemType", null)); - sessionConfig.setPassword(Context.getConfig().getString("sms.smpp.password", "password")); - sessionConfig.getLoggingOptions().setLogBytes(false); - sessionConfig.getLoggingOptions().setLogPdu(Context.getConfig().getBoolean("sms.smpp.logPdu")); - - sourceAddress = Context.getConfig().getString("sms.smpp.sourceAddress", ""); - commandSourceAddress = Context.getConfig().getString("sms.smpp.commandSourceAddress", sourceAddress); - submitTimeout = Context.getConfig().getInteger("sms.smpp.submitTimeout", 10000); - - requestDlr = Context.getConfig().getBoolean("sms.smpp.requestDlr"); - detectDlrByOpts = Context.getConfig().getBoolean("sms.smpp.detectDlrByOpts"); - - notificationsCharsetName = Context.getConfig().getString("sms.smpp.notificationsCharset", - CharsetUtil.NAME_UCS_2); - notificationsDataCoding = (byte) Context.getConfig().getInteger("sms.smpp.notificationsDataCoding", - SmppConstants.DATA_CODING_UCS2); - commandsCharsetName = Context.getConfig().getString("sms.smpp.commandsCharset", - CharsetUtil.NAME_GSM); - commandsDataCoding = (byte) Context.getConfig().getInteger("sms.smpp.commandsDataCoding", - SmppConstants.DATA_CODING_DEFAULT); - - - sourceTon = (byte) Context.getConfig().getInteger("sms.smpp.sourceTon", SmppConstants.TON_ALPHANUMERIC); - commandSourceTon = (byte) Context.getConfig().getInteger("sms.smpp.commandSourceTon", sourceTon); - sourceNpi = (byte) Context.getConfig().getInteger("sms.smpp.sourceNpi", SmppConstants.NPI_UNKNOWN); - commandSourceNpi = (byte) Context.getConfig().getInteger("sms.smpp.commandSourceNpi", sourceNpi); - - destTon = (byte) Context.getConfig().getInteger("sms.smpp.destTon", SmppConstants.TON_INTERNATIONAL); - destNpi = (byte) Context.getConfig().getInteger("sms.smpp.destNpi", SmppConstants.NPI_E164); - - enquireLinkPeriod = Context.getConfig().getInteger("sms.smpp.enquireLinkPeriod", 60000); - enquireLinkTimeout = Context.getConfig().getInteger("sms.smpp.enquireLinkTimeout", 10000); - enquireLinkExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); - String name = sessionConfig.getName(); - thread.setName("EnquireLink-" + name); - return thread; - } - }); - - reconnectionDelay = Context.getConfig().getInteger("sms.smpp.reconnectionDelay", 10000); - reconnectionExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); - String name = sessionConfig.getName(); - thread.setName("Reconnection-" + name); - return thread; - } - }); - - scheduleReconnect(); - } - - public synchronized SmppSession getSession() { - return smppSession; - } - - public String mapDataCodingToCharset(byte dataCoding) { - switch (dataCoding) { - case SmppConstants.DATA_CODING_LATIN1: - return CharsetUtil.NAME_ISO_8859_1; - case SmppConstants.DATA_CODING_UCS2: - return CharsetUtil.NAME_UCS_2; - default: - return CharsetUtil.NAME_GSM; - } - } - - public boolean getDetectDlrByOpts() { - return detectDlrByOpts; - } - - protected synchronized void reconnect() { - try { - disconnect(); - smppSession = clientBootstrap.bind(sessionConfig, sessionHandler); - stopReconnectionkTask(); - runEnquireLinkTask(); - LOGGER.info("SMPP session connected"); - } catch (SmppTimeoutException | SmppChannelException - | UnrecoverablePduException | InterruptedException error) { - LOGGER.warn("Unable to connect to SMPP server: ", error); - } - } - - public void scheduleReconnect() { - if (reconnectionTask == null || reconnectionTask.isDone()) { - reconnectionTask = reconnectionExecutor.scheduleWithFixedDelay( - new ReconnectionTask(this), - reconnectionDelay, reconnectionDelay, TimeUnit.MILLISECONDS); - } - } - - private void stopReconnectionkTask() { - if (reconnectionTask != null) { - reconnectionTask.cancel(false); - } - } - - private void disconnect() { - stopEnquireLinkTask(); - destroySession(); - } - - private void runEnquireLinkTask() { - enquireLinkTask = enquireLinkExecutor.scheduleWithFixedDelay( - new EnquireLinkTask(this, enquireLinkTimeout), - enquireLinkPeriod, enquireLinkPeriod, TimeUnit.MILLISECONDS); - } - - private void stopEnquireLinkTask() { - if (enquireLinkTask != null) { - enquireLinkTask.cancel(true); - } - } - - private void destroySession() { - if (smppSession != null) { - LOGGER.info("Cleaning up SMPP session... "); - smppSession.destroy(); - smppSession = null; - } - } - - @Override - public synchronized void sendMessageSync(String destAddress, String message, boolean command) - throws MessageException, InterruptedException, IllegalStateException { - if (getSession() != null && getSession().isBound()) { - try { - SubmitSm submit = new SubmitSm(); - byte[] textBytes; - textBytes = CharsetUtil.encode(message, command ? commandsCharsetName : notificationsCharsetName); - submit.setDataCoding(command ? commandsDataCoding : notificationsDataCoding); - if (requestDlr) { - submit.setRegisteredDelivery(SmppConstants.REGISTERED_DELIVERY_SMSC_RECEIPT_REQUESTED); - } - - if (textBytes != null && textBytes.length > 255) { - submit.addOptionalParameter(new Tlv(SmppConstants.TAG_MESSAGE_PAYLOAD, textBytes, - "message_payload")); - } else { - submit.setShortMessage(textBytes); - } - - submit.setSourceAddress(command ? new Address(commandSourceTon, commandSourceNpi, commandSourceAddress) - : new Address(sourceTon, sourceNpi, sourceAddress)); - submit.setDestAddress(new Address(destTon, destNpi, destAddress)); - SubmitSmResp submitResponce = getSession().submit(submit, submitTimeout); - if (submitResponce.getCommandStatus() == SmppConstants.STATUS_OK) { - LOGGER.info("SMS submitted, message id: " + submitResponce.getMessageId()); - } else { - throw new IllegalStateException(submitResponce.getResultMessage()); - } - } catch (SmppChannelException | RecoverablePduException - | SmppTimeoutException | UnrecoverablePduException error) { - throw new MessageException(error); - } - } else { - throw new MessageException(new SmppChannelException("SMPP session is not connected")); - } - } - - @Override - public void sendMessageAsync(final String destAddress, final String message, final boolean command) { - executorService.execute(new Runnable() { - @Override - public void run() { - try { - sendMessageSync(destAddress, message, command); - } catch (MessageException | InterruptedException | IllegalStateException error) { - LOGGER.warn("SMS sending error", error); - } - } - }); - } - -} diff --git a/src/org/traccar/sms/smpp/TextMessageEventHandler.java b/src/org/traccar/sms/smpp/TextMessageEventHandler.java deleted file mode 100644 index 37c29972d..000000000 --- a/src/org/traccar/sms/smpp/TextMessageEventHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 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.sms.smpp; - -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Event; - -public final class TextMessageEventHandler { - - private TextMessageEventHandler() { - } - - public static void handleTextMessage(String phone, String message) { - Device device = Context.getDeviceManager().getDeviceByPhone(phone); - if (device != null && Context.getNotificationManager() != null) { - Event event = new Event(Event.TYPE_TEXT_MESSAGE, device.getId()); - event.set("message", message); - Context.getNotificationManager().updateEvent(event, null); - } - } - -} diff --git a/src/org/traccar/web/ConsoleServlet.java b/src/org/traccar/web/ConsoleServlet.java deleted file mode 100644 index 2b38a935a..000000000 --- a/src/org/traccar/web/ConsoleServlet.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.web; - -import org.h2.server.web.ConnectionInfo; -import org.h2.server.web.WebServlet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class ConsoleServlet extends WebServlet { - - private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleServlet.class); - - @Override - public void init() { - super.init(); - - try { - Field field = WebServlet.class.getDeclaredField("server"); - field.setAccessible(true); - org.h2.server.web.WebServer server = (org.h2.server.web.WebServer) field.get(this); - - ConnectionInfo connectionInfo = new ConnectionInfo("Traccar|" - + Context.getConfig().getString("database.driver") + "|" - + Context.getConfig().getString("database.url") + "|" - + Context.getConfig().getString("database.user")); - - Method method; - - method = org.h2.server.web.WebServer.class.getDeclaredMethod("updateSetting", ConnectionInfo.class); - method.setAccessible(true); - method.invoke(server, connectionInfo); - - method = org.h2.server.web.WebServer.class.getDeclaredMethod("setAllowOthers", boolean.class); - method.setAccessible(true); - method.invoke(server, true); - - } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - LOGGER.warn("Console reflection error", e); - } - } - -} diff --git a/src/org/traccar/web/CsvBuilder.java b/src/org/traccar/web/CsvBuilder.java deleted file mode 100644 index 3fe7e408f..000000000 --- a/src/org/traccar/web/CsvBuilder.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.web; - -import java.beans.Introspector; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -import com.fasterxml.jackson.core.JsonProcessingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.helper.DateUtil; - -public class CsvBuilder { - - private static final Logger LOGGER = LoggerFactory.getLogger(CsvBuilder.class); - - private static final String LINE_ENDING = "\r\n"; - private static final String SEPARATOR = ";"; - - private StringBuilder builder = new StringBuilder(); - - private void addLineEnding() { - builder.append(LINE_ENDING); - } - private void addSeparator() { - builder.append(SEPARATOR); - } - - private SortedSet<Method> getSortedMethods(Object object) { - Method[] methodArray = object.getClass().getMethods(); - SortedSet<Method> methods = new TreeSet<>(new Comparator<Method>() { - @Override - public int compare(Method m1, Method m2) { - if (m1.getName().equals("getAttributes") && !m1.getName().equals(m2.getName())) { - return 1; - } - if (m2.getName().equals("getAttributes") && !m1.getName().equals(m2.getName())) { - return -1; - } - return m1.getName().compareTo(m2.getName()); - } - }); - methods.addAll(Arrays.asList(methodArray)); - return methods; - } - - public void addLine(Object object) { - - SortedSet<Method> methods = getSortedMethods(object); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { - try { - if (method.getReturnType().equals(boolean.class)) { - builder.append(method.invoke(object)); - addSeparator(); - } else if (method.getReturnType().equals(int.class)) { - builder.append(method.invoke(object)); - addSeparator(); - } else if (method.getReturnType().equals(long.class)) { - builder.append(method.invoke(object)); - addSeparator(); - } else if (method.getReturnType().equals(double.class)) { - builder.append(method.invoke(object)); - addSeparator(); - } else if (method.getReturnType().equals(String.class)) { - builder.append((String) method.invoke(object)); - addSeparator(); - } else if (method.getReturnType().equals(Date.class)) { - Date value = (Date) method.invoke(object); - builder.append(DateUtil.formatDate(value)); - addSeparator(); - } else if (method.getReturnType().equals(Map.class)) { - Map value = (Map) method.invoke(object); - if (value != null) { - try { - String map = Context.getObjectMapper().writeValueAsString(value); - map = map.replaceAll("[\\{\\}\"]", ""); - map = map.replaceAll(",", " "); - builder.append(map); - addSeparator(); - } catch (JsonProcessingException e) { - LOGGER.warn("Map JSON formatting error", e); - } - } - } - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Reflection invocation error", error); - } - } - } - addLineEnding(); - } - - public void addHeaderLine(Object object) { - - SortedSet<Method> methods = getSortedMethods(object); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { - String name = Introspector.decapitalize(method.getName().substring(3)); - if (!name.equals("class")) { - builder.append(name); - addSeparator(); - } - } - } - addLineEnding(); - } - - public void addArray(Collection<?> array) { - for (Object object : array) { - switch (object.getClass().getSimpleName().toLowerCase()) { - case "string": - builder.append(object.toString()); - addLineEnding(); - break; - case "long": - builder.append((long) object); - addLineEnding(); - break; - case "double": - builder.append((double) object); - addLineEnding(); - break; - case "boolean": - builder.append((boolean) object); - addLineEnding(); - break; - default: - addLine(object); - break; - } - } - } - - public String build() { - return builder.toString(); - } - -} diff --git a/src/org/traccar/web/GpxBuilder.java b/src/org/traccar/web/GpxBuilder.java deleted file mode 100644 index 638d100e5..000000000 --- a/src/org/traccar/web/GpxBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 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.web; - -import java.util.Collection; - -import org.traccar.helper.DateUtil; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; - -public class GpxBuilder { - - private StringBuilder builder = new StringBuilder(); - private static final String HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" - + "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"Traccar\" version=\"1.1\" " - + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " - + "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 " - + "http://www.topografix.com/GPX/1/1/gpx.xsd\"><trk>\n"; - private static final String NAME = "<name>%1$s</name><trkseg>%n"; - private static final String POINT = "<trkpt lat=\"%1$f\" lon=\"%2$f\">" - + "<time>%3$s</time>" - + "<geoidheight>%4$f</geoidheight>" - + "<course>%5$f</course>" - + "<speed>%6$f</speed>" - + "</trkpt>%n"; - private static final String FOOTER = "</trkseg></trk></gpx>"; - - public GpxBuilder() { - builder.append(HEADER); - builder.append("<trkseg>\n"); - } - - public GpxBuilder(String name) { - builder.append(HEADER); - builder.append(String.format(NAME, name)); - } - - public void addPosition(Position position) { - builder.append(String.format(POINT, position.getLatitude(), position.getLongitude(), - DateUtil.formatDate(position.getFixTime()), position.getAltitude(), - position.getCourse(), UnitsConverter.mpsFromKnots(position.getSpeed()))); - } - - public void addPositions(Collection<Position> positions) { - for (Position position : positions) { - addPosition(position); - } - } - - public String build() { - builder.append(FOOTER); - return builder.toString(); - } - -} diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java deleted file mode 100644 index 70fef4ed3..000000000 --- a/src/org/traccar/web/WebServer.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2012 - 2019 Anton Tananaev (anton@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.web; - -import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.proxy.AsyncProxyServlet; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ErrorHandler; -import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.glassfish.jersey.jackson.JacksonFeature; -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.api.AsyncSocketServlet; -import org.traccar.api.CorsResponseFilter; -import org.traccar.api.MediaFilter; -import org.traccar.api.ObjectMapperProvider; -import org.traccar.api.ResourceErrorHandler; -import org.traccar.api.SecurityRequestFilter; -import org.traccar.api.resource.ServerResource; - -import javax.servlet.DispatcherType; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.IOException; -import java.io.Writer; -import java.net.InetSocketAddress; -import java.util.EnumSet; - -public class WebServer { - - private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); - - private Server server; - - private void initServer(Config config) { - - String address = config.getString("web.address"); - int port = config.getInteger("web.port", 8082); - if (address == null) { - server = new Server(port); - } else { - server = new Server(new InetSocketAddress(address, port)); - } - } - - public WebServer(Config config) { - - initServer(config); - - ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); - - int sessionTimeout = config.getInteger("web.sessionTimeout"); - if (sessionTimeout > 0) { - servletHandler.getSessionHandler().setMaxInactiveInterval(sessionTimeout); - } - - initApi(config, servletHandler); - - if (config.getBoolean("web.console")) { - servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); - } - - initWebApp(config, servletHandler); - - servletHandler.setErrorHandler(new ErrorHandler() { - @Override - protected void handleErrorPage( - HttpServletRequest request, Writer writer, int code, String message) throws IOException { - writer.write("<!DOCTYPE<html><head><title>Error</title></head><html><body>" - + code + " - " + HttpStatus.getMessage(code) + "</body></html>"); - } - }); - - HandlerList handlers = new HandlerList(); - initClientProxy(config, handlers); - handlers.addHandler(servletHandler); - server.setHandler(handlers); - } - - private void initClientProxy(Config config, HandlerList handlers) { - int port = config.getInteger("osmand.port"); - if (port != 0) { - ServletContextHandler servletHandler = new ServletContextHandler() { - @Override - public void doScope( - String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - if (target.equals("/") && request.getMethod().equals(HttpMethod.POST.asString())) { - super.doScope(target, baseRequest, request, response); - } - } - }; - ServletHolder servletHolder = new ServletHolder(new AsyncProxyServlet.Transparent()); - servletHolder.setInitParameter("proxyTo", "http://localhost:" + port); - servletHandler.addServlet(servletHolder, "/"); - handlers.addHandler(servletHandler); - } - } - - private void initWebApp(Config config, ServletContextHandler servletHandler) { - ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); - servletHolder.setInitParameter("resourceBase", new File(config.getString("web.path")).getAbsolutePath()); - if (config.getBoolean("web.debug")) { - servletHandler.setWelcomeFiles(new String[] {"debug.html", "index.html"}); - } else { - String cache = config.getString("web.cacheControl"); - if (cache != null && !cache.isEmpty()) { - servletHolder.setInitParameter("cacheControl", cache); - } - servletHandler.setWelcomeFiles(new String[] {"release.html", "index.html"}); - } - servletHandler.addServlet(servletHolder, "/*"); - } - - private void initApi(Config config, ServletContextHandler servletHandler) { - servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); - - if (config.hasKey("media.path")) { - ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); - servletHolder.setInitParameter("resourceBase", new File(config.getString("media.path")).getAbsolutePath()); - servletHolder.setInitParameter("dirAllowed", config.getString("media.dirAllowed", "false")); - servletHolder.setInitParameter("pathInfoOnly", "true"); - servletHandler.addServlet(servletHolder, "/api/media/*"); - servletHandler.addFilter(MediaFilter.class, "/api/media/*", EnumSet.allOf(DispatcherType.class)); - } - - ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfig.registerClasses(JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class); - resourceConfig.registerClasses(SecurityRequestFilter.class, CorsResponseFilter.class); - resourceConfig.packages(ServerResource.class.getPackage().getName()); - servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); - } - - public void start() { - try { - server.start(); - } catch (Exception error) { - LOGGER.warn("Web server start failed", error); - } - } - - public void stop() { - try { - server.stop(); - } catch (Exception error) { - LOGGER.warn("Web server stop failed", error); - } - } - -} |