Example usage for io.netty.buffer ByteBuf getUnsignedByte

List of usage examples for io.netty.buffer ByteBuf getUnsignedByte

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf getUnsignedByte.

Prototype

public abstract short getUnsignedByte(int index);

Source Link

Document

Gets an unsigned byte at the specified absolute index in this buffer.

Usage

From source file:org.traccar.protocol.AplicomFrameDecoder.java

License:Apache License

@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();//from   w w  w .  j a  v a 2s.  c  om
    }

    // 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;
}

From source file:org.traccar.protocol.At2000ProtocolDecoder.java

License:Apache License

@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
    }//from   ww  w . j  a v a2s .c o  m

    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;
}

From source file:org.traccar.protocol.AutoFonFrameDecoder.java

License:Apache License

@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {

    // Check minimum length
    if (buf.readableBytes() < 12) {
        return null;
    }/*from ww w.java 2 s  .c o m*/

    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;
}

From source file:org.traccar.protocol.BceProtocolDecoder.java

License:Apache License

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

    ByteBuf buf = (ByteBuf) msg;//from  www .j  av  a  2s  .  c  o  m

    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;
}

From source file:org.traccar.protocol.CalAmpProtocolDecoder.java

License:Apache License

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
    }//from   w ww  . j av  a 2s.  c o m
    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;
}

From source file:org.traccar.protocol.CellocatorFrameDecoder.java

License:Apache License

@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {

    if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) {
        return null;
    }//from  w  ww  .jav  a 2s. c o  m

    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;
}

From source file:org.traccar.protocol.ContinentalProtocolDecoder.java

License:Apache License

@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;
    }/*  ww  w.  j  ava 2  s  .  c o m*/

    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;
}

From source file:org.traccar.protocol.EgtsFrameDecoder.java

License:Apache License

@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {

    if (buf.readableBytes() < 10) {
        return null;
    }//from  w w  w. ja v a 2  s .  co m

    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;
}

From source file:org.traccar.protocol.EgtsProtocolDecoder.java

License:Apache License

@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
        }//ww w.  ja v a2 s  .c  om

        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;
}

From source file:org.traccar.protocol.Gl200BinaryProtocolDecoder.java

License:Apache License

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;
    }/*  ww  w .  j a  v  a  2 s. c o m*/

    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;
}