Package de.uniluebeck.itm.ncoap.communication.codec

Source Code of de.uniluebeck.itm.ncoap.communication.codec.OptionEncoding

/**
* Copyright (c) 2012, Oliver Kleine, Institute of Telematics, University of Luebeck
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*  - Redistributions of source messageCode must retain the above copyright notice, this list of conditions and the following
*    disclaimer.
*
*  - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*    following disclaimer in the documentation and/or other materials provided with the distribution.
*
*  - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*    products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package de.uniluebeck.itm.ncoap.communication.codec;

import com.google.common.collect.Lists;
import de.uniluebeck.itm.ncoap.AbstractCoapTest;
import de.uniluebeck.itm.ncoap.communication.codec.tools.CoapTestEncoder;
import de.uniluebeck.itm.ncoap.message.options.OptionValue;
import de.uniluebeck.itm.ncoap.message.options.StringOptionValue;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Collection;

import static org.junit.Assert.assertEquals;

/**
* Created with IntelliJ IDEA.
* User: olli
* Date: 09.11.13
* Time: 21:07
* To change this template use File | Settings | File Templates.
*/
@RunWith(Parameterized.class)
public class OptionEncoding extends AbstractCoapTest {


    @Parameterized.Parameters(name = "Test: [Prev. No. {0}, Option No. {1}, value: {2}]")
    public static Collection<Object[]> data() throws Exception {
        return Lists.newArrayList(
                new Object[]{0, OptionValue.Name.URI_HOST, "www.example.org"},
                new Object[]{0, OptionValue.Name.URI_HOST, "WWW.EXAMPLE.ORG"},
                new Object[]{0, OptionValue.Name.URI_HOST, "WwW.eXaMpLe.OrG"},
                new Object[]{0, OptionValue.Name.URI_HOST, "WwW.this-is-a-long-uri-host-part.OrG"},

                //Short Proxy URI
                new Object[]{0, OptionValue.Name.PROXY_URI, "coap://www.example.org/path/to/service"},

                //Very long Proxy URI
                new Object[]{30, OptionValue.Name.PROXY_URI, "coap://www.example.org/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service/this/is/a/very/long/path/to/service/" +
                        "this/is/a/very/long/path/to/service"}


        );
    }

    private Logger log = Logger.getLogger(this.getClass().getName());

    private CoapTestEncoder coapTestEncoder;

    private int previousOptionNumber;
    private int optionNumber;
    private OptionValue optionValue;

    private ChannelBuffer encodedOption;


    private OptionEncoding(int previousOptionNumber, int optionNumber, OptionValue optionValue){
        this.coapTestEncoder = new CoapTestEncoder();
        this.previousOptionNumber = previousOptionNumber;
        this.optionNumber = optionNumber;
        this.optionValue = optionValue;
    }


    public OptionEncoding(int previousOptionNumber, int optionNumber, String value) throws Exception{
        this(previousOptionNumber, optionNumber, new StringOptionValue(optionNumber, value));
    }


    @Before
    public void encodeOption() throws Exception {
        log.info("Start Tests with Option " + optionValue);
        encodedOption = ChannelBuffers.dynamicBuffer();
        coapTestEncoder.encodeOption(encodedOption, optionNumber, optionValue, previousOptionNumber);
    }

    @Test
    public void testDeltaPartOfFirstByte(){
        int expectedDelta = this.optionNumber - this.previousOptionNumber;

        ChannelBuffer buffer = ChannelBuffers.copiedBuffer(encodedOption);

        int firstByte = buffer.readByte() & 0xFF;

        if(expectedDelta < 13){
            assertEquals("Delta part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedDelta), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte >>> 4), 4)
            );
        }

        if(expectedDelta >= 13 && expectedDelta < 269){
            assertEquals("Delta part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(13), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte >>> 4), 4)
            );
        }

        if(expectedDelta >= 269 && expectedDelta < 65804){
            assertEquals("Delta part of first byte does is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(14), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte >>> 4), 4)
            );
        }
    }

    @Test
    public void testLengthPartOfFirstByte(){
        int expectedLength = this.optionValue.getValue().length;

        ChannelBuffer buffer = ChannelBuffers.copiedBuffer(encodedOption);

        int firstByte = buffer.readByte() & 0xFF;

        if(expectedLength < 13){
            assertEquals("Length part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedLength), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte & 0x0F), 4)
            );

            assertEquals("Encoded length and readable bytes do not match, ",
                    (firstByte & 0x0F) + 269, buffer.readableBytes());
        }

        if(expectedLength >= 13 && expectedLength < 269){
            assertEquals("Length part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(13), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte & 0x0F), 4)
            );
        }

        if(expectedLength >= 269 && expectedLength < 65804){
            assertEquals("Length part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(14), 4),
                    getZeroPaddedBinaryString(Integer.toBinaryString(firstByte & 0x0F), 4)
            );
        }
    }

    @Test
    public void testExtendedDelta(){

        int expectedDelta = this.optionNumber - this.previousOptionNumber;

        ChannelBuffer buffer = ChannelBuffers.copiedBuffer(encodedOption);
        buffer.readByte();

        if(expectedDelta >= 13 && expectedDelta < 269){
            int extendedDelta = (buffer.readByte() & 0xFF);
            assertEquals("Extended delta part is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedDelta - 13), 8),
                    getZeroPaddedBinaryString(Integer.toBinaryString(extendedDelta), 8));
        }

        if(expectedDelta >= 269 && expectedDelta < 65804){
            int extendedDelta = ((buffer.readByte() & 0xFF) << 8 | (buffer.readByte() & 0xFF));
            assertEquals("Length part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedDelta - 269), 16),
                    getZeroPaddedBinaryString(Integer.toBinaryString(extendedDelta), 16)
            );
        }
    }

    @Test
    public void testExtendedLength(){

        int expectedLength = optionValue.getValue().length;

        ChannelBuffer buffer = ChannelBuffers.copiedBuffer(encodedOption);
        int firstByte = buffer.readByte();
        int deltaPart = (firstByte & 0xFF) >>> 4 ;

        //read and ignore next byte (extended option delta)
        if(deltaPart == 13){
            log.debug("Skip next byte (extended delta)");
            buffer.readByte();
        }

        //read and ignore next 2 bytes (extended option delta)
        if(deltaPart == 14){
            log.debug("Skip next 2 bytes (extended delta)");
            buffer.readBytes(new byte[2]);
        }

        if(expectedLength >= 13 && expectedLength < 269){
            log.info("Expected extended length value: " + (expectedLength - 13));
            int extendedLength = (buffer.readByte() & 0xFF);

            assertEquals("Extended Length part is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedLength - 13), 8),
                    getZeroPaddedBinaryString(Integer.toBinaryString(extendedLength), 8));

            assertEquals("Encoded length and readable bytes do not match, ",
                    extendedLength + 13, buffer.readableBytes());
        }

        if(expectedLength >= 269 && expectedLength < 65804){
            log.info("Expected extended length value: " + (expectedLength - 269));
            int extendedLength = ((buffer.readByte() & 0xFF) << 8 | (buffer.readByte() & 0xFF));

            assertEquals("Length part of first byte is incorrect, ",
                    getZeroPaddedBinaryString(Integer.toBinaryString(expectedLength - 269), 16),
                    getZeroPaddedBinaryString(Integer.toBinaryString(extendedLength), 16)
            );

            assertEquals("Encoded length and readable bytes do not match, ",
                    extendedLength + 269, buffer.readableBytes());
        }
    }



    private static String getZeroPaddedBinaryString(String original, int expectedLength){
        String result = original;
        while(result.length() < expectedLength)
            result = 0 + result;

        return result;
    }



    @After
    public void justWaitASecond() throws InterruptedException {
        Thread.sleep(100);
    }


    @Override
    public void setupLogging() throws Exception {
        Logger.getLogger("de.uniluebeck.itm.ncoap.communication.encoding").setLevel(Level.DEBUG);
    }
}
TOP

Related Classes of de.uniluebeck.itm.ncoap.communication.codec.OptionEncoding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.