Trouble with new protocol

zzmyers4 years ago

I was running Traccar 3.10 with a custom protocol. I upgraded to Traccar 4.8 and again added my custom protocol. However, the custom protocol is not working and nothing is getting logged by Traccar. I can't figure out what is wrong with it. Essentially I have another program which talks to the trackers and then that program sends the data to Traccar in a simple text string format.

Right now I am stumped on what the problem could be as this protocol has been working for 2 years on Traccar 3.10. Please help!

This is the NavisysProtocol.java:

package org.traccar.protocol;

import org.traccar.BaseProtocol;
import org.traccar.PipelineBuilder;
import org.traccar.TrackerServer;

public class NavisysProtocol extends BaseProtocol {

    public NavisysProtocol() {
        addServer(new TrackerServer(false, getName()) {
            @Override
            protected void addProtocolHandlers(PipelineBuilder pipeline) {
                pipeline.addLast(new NavisysProtocolDecoder(NavisysProtocol.this));
            }
        });
    }
}

This is the NavisysProtocolDecoder.jave:

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.helper.DateBuilder;
import org.traccar.model.Position;

import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Date;

public class NavisysProtocolDecoder extends BaseProtocolDecoder {

    public NavisysProtocolDecoder(NavisysProtocol protocol) {
        super(protocol);
    }

    private Object processEvent(Channel channel, SocketAddress remoteAddress, String sentence) {
        Position position = new Position();
        position.setProtocol(getProtocolName());

        String[] parts = sentence.split(",");

        String imei = parts[1];
        DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
        if (deviceSession == null) {
            return null;
        }
        position.setDeviceId(deviceSession.getDeviceId());
        DateBuilder dateBuilder = new DateBuilder()
                .setDate(Integer.parseInt(parts[3].substring(0, 4)),
                        Integer.parseInt(parts[3].substring(5, 7)),
                        Integer.parseInt(parts[3].substring(8, 10)));
        dateBuilder.setTime(Integer.parseInt(parts[3].substring(11, 13)),
                Integer.parseInt(parts[3].substring(14, 16)),
                Integer.parseInt(parts[3].substring(17, 19)));
        position.setTime(dateBuilder.getDate());

        switch (parts[2]) {
            case "BATTERY":
                // only report battery event if it is in the last 2 hours, prevents BS backlogged reports.
                Date time2 = new Date();
                long diff = time2.getTime() - position.getDeviceTime().getTime();
                if (diff < 7200000) {
                    position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
                }
                break;
            case "MOVE":
                position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
                break;
            case "CONNECT":
                position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_CONNECT);
                break;
            case "DISCONNECT":
                position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_DISCONNECT);
                break;
            default:
                break;
        }
        position.set(Position.KEY_EVENT, parts[2]);

        switch (parts[2]) {
            case "CONNECT":
            case "DISCONNECT":
                break;
            default:
                position.setLatitude(Double.parseDouble(parts[4]));
                position.setLongitude(Double.parseDouble(parts[5]));
                position.setAccuracy(Double.parseDouble(parts[8]));
                position.set(Position.KEY_STATUS, parts[7]);

                Double pct = Double.parseDouble(parts[6]);
                Long val = Math.round(pct * 100);
                position.set(Position.KEY_BATTERY, val + "%");
                break;
        }
        position.setValid(parts[7].equals("GPS_FIXED"));

        return position;
    }

    private Object processPosition(Channel channel, SocketAddress remoteAddress, String sentence) {
        Position position = new Position();
        position.setProtocol(getProtocolName());

        String[] parts = sentence.split(",");

        String imei = parts[1];
        DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
        if (deviceSession == null) {
            return null;
        }
        position.setDeviceId(deviceSession.getDeviceId());
        DateBuilder dateBuilder = new DateBuilder()
                .setDate(Integer.parseInt(parts[2].substring(0, 4)),
                        Integer.parseInt(parts[2].substring(5, 7)),
                        Integer.parseInt(parts[2].substring(8, 10)));
        dateBuilder.setTime(Integer.parseInt(parts[2].substring(11, 13)),
                Integer.parseInt(parts[2].substring(14, 16)),
                Integer.parseInt(parts[2].substring(17, 19)));

        Boolean valid = false;
        if (parts[6].equals("GPS_FIXED")) {
            valid = true;
        } else if (!parts[11].startsWith("0:0;")) {
            valid = true;
        }
        position.setValid(valid);

        position.setTime(dateBuilder.getDate());
        position.setLatitude(Double.parseDouble(parts[3]));
        position.setLongitude(Double.parseDouble(parts[4]));
        position.setSpeed(Double.parseDouble(parts[9]));
        position.setAltitude(Double.parseDouble(parts[8]));
        position.setAccuracy(Double.parseDouble(parts[10]));
        position.set(Position.KEY_STATUS, parts[6]);
        position.set(Position.KEY_SATELLITES, parts[11]);

        Double pct = Double.parseDouble(parts[5]);
        Long val = Math.round(pct * 100);
        position.set(Position.KEY_BATTERY, val + "%");

        return position;
    }

    @Override
    protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {

        ByteBuf buf = (ByteBuf) msg;
        String sentence = buf.toString(StandardCharsets.US_ASCII).trim();

        if (sentence.contains("$POS,")) {
            return processPosition(channel, remoteAddress, sentence);
        } else if (sentence.contains("$EVENT,")) {
            return processEvent(channel, remoteAddress, sentence);
        } else {
            return null;
        }

    }
}
Anton Tananaev4 years ago

Have you tried debugging the problem? I don't think anyone would be able to tell you anything just by looking at this code.