nss.delta.agentmanager.utils.OFMessageDecoder.java Source code

Java tutorial

Introduction

Here is the source code for nss.delta.agentmanager.utils.OFMessageDecoder.java

Source

/**
 *    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
 *
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *    License for the specific language governing permissions and limitations
 *    under the License.
 **/

package nss.delta.agentmanager.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFMessageReader;
import org.projectfloodlight.openflow.protocol.OFVersion;

/**
 * Decode an openflow message from a channel, for use in a netty pipeline.
 *
 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
 */
public class OFMessageDecoder extends ByteToMessageDecoder {

    private OFMessageReader<OFMessage> reader;

    public OFMessageDecoder() {
        setReader();
    }

    public OFMessageDecoder(OFVersion version) {
        setVersion(version);
        setReader();
    }

    private void setReader() {
        reader = OFFactories.getGenericReader();
    }

    public void setVersion(OFVersion version) {
        OFFactory factory = OFFactories.getFactory(version);
        this.reader = factory.getReader();
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (!ctx.channel().isActive()) {
            // In testing, I see decode being called AFTER decode last.
            // This check avoids that from reading corrupted frames
            return;
        }

        // Note(andiw): netty4 adds support for more efficient handling of lists messages in the
        // pipeline itself.
        // Instead of constructing a list of messages here, we could also just add the individual
        // messages to the "out" list provided by netty. This would require changing all the handlers
        // in the pipeline to accept "OFMessage" instead of "Iterable<OFMessage>". Probably
        // a good idea, but left for a future cleanup.

        OFMessage singleMessage = null;
        List<OFMessage> list = null;
        boolean first = true;
        for (;;) {
            OFMessage message = reader.readFrom(in);
            if (message == null) {
                break;
            }
            if (first) {
                // first message read
                singleMessage = message;
                first = false;
            } else {
                // more messages read, use the list
                if (list == null) {
                    list = new ArrayList<>();
                    list.add(singleMessage);
                    singleMessage = null;
                }
                list.add(message);
            }
        }
        if (list != null) {
            out.add(list);
        } else if (singleMessage != null) {
            out.add(Collections.singletonList(singleMessage));
        }
    }
}