Android Open Source - base_controller Husky Packet Reader






From Project

Back to project page base_controller.

License

The source code is released under:

Apache License

If you think the Android project base_controller listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.github.c77.base_driver.husky;
/*w ww  .  j a  va  2  s .  co m*/
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * @author jcerruti@creativa77.com (Julian Cerruti)
 */
public class HuskyPacketReader {
    public enum parserState {
        READY, PARTIAL
    };
    private parserState curState;
    private volatile byte[] stored;
    private int storedSize;

    private int storedIndex;
    private HuskyPacket parsedPacket;

    private static final Log log = LogFactory.getLog(HuskyPacketReader.class);

    public HuskyPacketReader() {
        curState = parserState.READY;

        stored = new byte[500]; // Should be big enough for the biggest packets
        storedSize = 0;
        storedIndex = 0;
    }

    /**
     * Parses incoming bytes into HuskyPacket objects
     * @return <code>null</code> if the packet is incomplete
     */
    public HuskyPacket parse(ByteBuffer buffer) throws HuskyParserException {
        // Samples:
        //  aa0df2000c030000000402550800de8f  (echo:out of range)
        //  aa0df20008040000000402550100d829
        //  aa0df200f7 | 030000000402550800ef4f (split message)
        //  aa0d | f200 d310 0000 0004 0255 0000 c42c

        int bufferSize = buffer.array().length;
        if(curState == parserState.READY) {
            // Initialize a new buffer copy
            buffer.get(stored, 0, bufferSize);
            storedSize = bufferSize;
            parsedPacket = new HuskyPacket();
        } else {
            // Add to the previous buffer and keep parsing
            buffer.get(stored, storedSize, bufferSize);
            storedSize += bufferSize;
        }

        ByteBuffer bufferParse = ByteBuffer.wrap(stored);
        bufferParse.order(ByteOrder.LITTLE_ENDIAN);
        curState = parserState.PARTIAL;
main:   while(storedIndex < storedSize) {
            switch(storedIndex) {
                case 0:     // SOH
                    log.debug("Parsing SOH");
                    parsedPacket.soh = bufferParse.get(storedIndex);
                    if(parsedPacket.soh != (byte)0xAA) {
                        // Reset state so that we can wait until the correct packet start.
                        storedSize = 0;
                        storedIndex = 0;
                        curState = parserState.READY;
                        throw new HuskyParserException("SOH byte doesn't match: " + parsedPacket.soh);
                    }
                    storedIndex += 1;
                    break;
                case 1:     // length
                    log.debug("Parsing length");
                    parsedPacket.length = bufferParse.get(storedIndex);
                    storedIndex += 1;
                    break;
                case 2:     // length complement
                    log.debug("Parsing length complement");
                    parsedPacket.lengthComplement = bufferParse.get(storedIndex);
                    // TODO: Verify complement against length
                    storedIndex += 1;
                    break;
                case 3:     // version
                    log.debug("Parsing version");
                    parsedPacket.version = bufferParse.get(storedIndex);
                    // TODO: Verify version
                    storedIndex += 1;
                    break;
                case 4:     // timestamp
                    log.debug("Parsing timestamp");
                    // Make sure we have enough data to parse this otherwise skip
                    if(storedSize - storedIndex < 4) {
                        break main;
                    }
                    parsedPacket.timestamp = bufferParse.getInt(storedIndex);
                    storedIndex += 4;
                    break;
                case 8:     // flags
                    log.debug("Parsing flags");
                    parsedPacket.flags = bufferParse.get(storedIndex);
                    storedIndex += 1;
                    break;
                case 9:     // message type
                    log.debug("Parsing message type");
                    parsedPacket.messageType = bufferParse.getChar(storedIndex);
                    if(storedSize - storedIndex < 2) {
                        break main;
                    }
                    storedIndex += 2;
                    break;
                case 11:     // stx
                    log.debug("Parsing STX");
                    parsedPacket.stx = bufferParse.get(storedIndex);
                    if(parsedPacket.stx != (byte)0x55) {
                        throw new HuskyParserException("STX byte doesn't match: " + parsedPacket.stx);
                    }
                    storedIndex += 1;
                    break;
                case 12:     // payload and CRC
                    log.debug("Parsing payload and CRC");
                    int payloadAndCrcLength = parsedPacket.length - 9;
                    if(storedSize - storedIndex < payloadAndCrcLength) {
                        break main;
                    }
                    parsedPacket.payload = new byte[payloadAndCrcLength - 2];
                    System.arraycopy(stored, 12, parsedPacket.payload, 0, parsedPacket.payload.length);
                    bufferParse.getChar(storedIndex + parsedPacket.payload.length);
                    // TODO: Verify checksum
                    storedIndex = 0;
                    curState = parserState.READY;
                    break main;
            }
        }

        if(curState == parserState.READY) {
            return parsedPacket;
        } else {
            return null;
        }
    }

    /**
     * Very simple command-line testing for parsing known packet values
     */
    public static void main(String args[]) throws java.lang.Exception {
        HuskyPacketReader reader = new HuskyPacketReader();

        // Try parsing entire packet in one shot (most common method)
        HuskyPacket packet = tryParse(reader, "aa0df2000c030000000402550800de8f");
        System.out.println("Packet = " + packet);

        // Try parsing packet in two passes
        System.out.println("Packet 1/2 = " + tryParse(reader, "aa0df200f7"));
        System.out.println("Packet 1/2 = " + tryParse(reader, "030000000402550800ef4f"));
    }
    private static HuskyPacket tryParse(HuskyPacketReader reader, String hexArrayString) throws java.lang.Exception {
        return reader.parse(ByteBuffer.wrap(Hex.decodeHex(hexArrayString.toCharArray())));
    }
}




Java Source Code List

com.github.c77.base_controller.BaseControllerNode.java
com.github.c77.base_controller.BaseOdomPublisher.java
com.github.c77.base_controller.BaseStatusPublisher.java
com.github.c77.base_driver.AbstractOdometryStatus.java
com.github.c77.base_driver.BaseDevice.java
com.github.c77.base_driver.BaseStatus.java
com.github.c77.base_driver.InertialInformation.java
com.github.c77.base_driver.OdometryStatus.java
com.github.c77.base_driver.create.CreateBaseDevice.java
com.github.c77.base_driver.husky.HuskyBaseDevice.java
com.github.c77.base_driver.husky.HuskyBaseUtils.java
com.github.c77.base_driver.husky.HuskyOdometryStatus.java
com.github.c77.base_driver.husky.HuskyPacketReader.java
com.github.c77.base_driver.husky.HuskyPacket.java
com.github.c77.base_driver.husky.HuskyParserException.java
com.github.c77.base_driver.kobuki.KobukiBaseDevice.java
com.github.c77.base_driver.kobuki.KobukiOdometryStatus.java
com.github.c77.base_driver.kobuki.KobukiPacketParser.java
com.github.c77.base_driver.kobuki.KobukiPacketReader.java