Example usage for io.netty.buffer ByteBuf readUnsignedShortLE

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

Introduction

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

Prototype

public abstract int readUnsignedShortLE();

Source Link

Document

Gets an unsigned 16-bit short integer at the current readerIndex in the Little Endian Byte Order and increases the readerIndex by 2 in this buffer.

Usage

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

License:Apache License

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 {/*  ww  w .  j  ava  2s. c o m*/
        decodeTagOther(position, buf, tag);
    }
}

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

License:Apache License

private void decodeTagOther(Position position, ByteBuf buf, int tag) {
    switch (tag) {
    case 0x01:/*from w  ww . ja  v a 2s . c o m*/
        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;
    }
}

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

License:Apache License

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

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

License:Apache License

private Object decodePhoto(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception {

    int length = buf.readUnsignedShortLE();

    Position position = null;/*from w w w .j a  v a 2 s.co  m*/

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

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

License:Apache License

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;
    }//from  w ww.  ja  va 2  s .c  om

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

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

License:Apache License

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

    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
}

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

License:Apache License

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

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

License:Apache License

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;
    }//from www  .j a va  2 s .  c om

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

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

License:Apache License

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);//from   w  ww. java 2  s  .  c o m

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

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

License:Apache License

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

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