package net.onrc.onos.of.ctl.internal;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.RejectedExecutionException;

import net.onrc.onos.of.ctl.IOFSwitch;
import net.onrc.onos.of.ctl.IOFSwitch.PortChangeEvent;
import net.onrc.onos.of.ctl.Role;
import net.onrc.onos.of.ctl.annotations.LogMessageDoc;
import net.onrc.onos.of.ctl.annotations.LogMessageDocs;
import net.onrc.onos.of.ctl.debugcounter.IDebugCounterService.CounterException;
import net.onrc.onos.of.ctl.internal.Controller.Counters;
import net.onrc.onos.of.ctl.internal.OFChannelHandler.ChannelState.RoleReplyInfo;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.jboss.netty.handler.timeout.ReadTimeoutException;
import org.projectfloodlight.openflow.exceptions.OFParseError;
import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
import org.projectfloodlight.openflow.protocol.OFBadRequestCode;
import org.projectfloodlight.openflow.protocol.OFBarrierReply;
import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
import org.projectfloodlight.openflow.protocol.OFControllerRole;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFDescStatsRequest;
import org.projectfloodlight.openflow.protocol.OFEchoReply;
import org.projectfloodlight.openflow.protocol.OFEchoRequest;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFErrorType;
import org.projectfloodlight.openflow.protocol.OFExperimenter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFFlowModFailedCode;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFGetConfigReply;
import org.projectfloodlight.openflow.protocol.OFGetConfigRequest;
import org.projectfloodlight.openflow.protocol.OFHello;
import org.projectfloodlight.openflow.protocol.OFHelloElem;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFQueueGetConfigReply;
import org.projectfloodlight.openflow.protocol.OFRoleReply;
import org.projectfloodlight.openflow.protocol.OFRoleRequest;
import org.projectfloodlight.openflow.protocol.OFSetConfig;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
import org.projectfloodlight.openflow.protocol.errormsg.OFRoleRequestFailedErrorMsg;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Channel handler deals with the switch connection and dispatches
 * switch messages to the appropriate locations.
 */
class OFChannelHandler extends IdleStateAwareChannelHandler {
    private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class);
    private static final long DEFAULT_ROLE_TIMEOUT_MS = 2 * 1000; // 10 sec
    private final Controller controller;
    private final Counters counters;
    private IOFSwitch sw;
    private long thisdpid; // channelHandler cached value of connected switch id
    private Channel channel;
    // State needs to be volatile because the HandshakeTimeoutHandler
    // needs to check if the handshake is complete
    private volatile ChannelState state;

    // All role messaging is handled by the roleChanger. The channel state machine
    // coordinates between the roleChanger and the controller-global-registry-service
    // to determine controller roles per switch.
    private RoleChanger roleChanger;
    // Used to coordinate between the controller and the cleanup thread(?)
    // for access to the global registry on a per switch basis.
    volatile Boolean controlRequested;
    // When a switch with a duplicate dpid is found (i.e we already have a
    // connected switch with the same dpid), the new switch is immediately
    // disconnected. At that point netty callsback channelDisconnected() which
    // proceeds to cleaup switch state - we need to ensure that it does not cleanup
    // switch state for the older (still connected) switch
    private volatile Boolean duplicateDpidFound;

    // Temporary storage for switch-features and port-description
    private OFFeaturesReply featuresReply;
    private OFPortDescStatsReply portDescReply;
    // a concurrent ArrayList to temporarily store port status messages
    // before we are ready to deal with them
    private final CopyOnWriteArrayList<OFPortStatus> pendingPortStatusMsg;

    //Indicates the openflow version used by this switch
    protected OFVersion ofVersion;
    protected OFFactory factory13;
    protected OFFactory factory10;

    /** transaction Ids to use during handshake. Since only one thread
     * calls into an OFChannelHandler instance, we don't need atomic.
     * We will count down
     */
    private int handshakeTransactionIds = -1;

    /**
     * Create a new unconnected OFChannelHandler.
     * @param controller
     */
    OFChannelHandler(Controller controller) {
        this.controller = controller;
        this.counters = controller.getCounters();
        this.roleChanger = new RoleChanger(DEFAULT_ROLE_TIMEOUT_MS);
        this.state = ChannelState.INIT;
        this.pendingPortStatusMsg = new CopyOnWriteArrayList<OFPortStatus>();
        factory13 = controller.getOFMessageFactory13();
        factory10 = controller.getOFMessageFactory10();
        controlRequested = Boolean.FALSE;
        duplicateDpidFound = Boolean.FALSE;
    }

    //*******************
    //  Role Handling
    //*******************

    /**
     * When we remove a pending role request we use this enum to indicate how we
     * arrived at the decision. When we send a role request to the switch, we
     * also use  this enum to indicate what we expect back from the switch, so the
     * role changer can match the reply to our expectation.
     */
    public enum RoleRecvStatus {
        /** The switch returned an error indicating that roles are not.
         * supported*/
        UNSUPPORTED,
        /** The request timed out. */
        NO_REPLY,
        /** The reply was old, there is a newer request pending. */
        OLD_REPLY,
        /**
         *  The reply's role matched the role that this controller set in the
         *  request message - invoked either initially at startup or to reassert
         *  current role.
         */
        MATCHED_CURRENT_ROLE,
        /**
         *  The reply's role matched the role that this controller set in the
         *  request message - this is the result of a callback from the
         *  global registry, followed by a role request sent to the switch.
         */
        MATCHED_SET_ROLE,
        /**
         * The reply's role was a response to the query made by this controller.
         */
        REPLY_QUERY,
        /** We received a role reply message from the switch
         *  but the expectation was unclear, or there was no expectation.
         */
        OTHER_EXPECTATION,
    }

    /**
     * Forwards to RoleChanger. See there.
     * @param role
     */
    public void sendRoleRequest(Role role, RoleRecvStatus expectation) {
        try {
            roleChanger.sendRoleRequest(role, expectation);
        } catch (IOException e) {
            log.error("Disconnecting switch {} due to IO Error: {}",
                    getSwitchInfoString(), e.getMessage());
            channel.close();
        }
    }

    // XXX S consider if necessary
    public void disconnectSwitch() {
        sw.disconnectSwitch();
    }

    /**
     * A utility class to handle role requests and replies for this channel.
     * After a role request is submitted the role changer keeps track of the
     * pending request, collects the reply (if any) and times out the request
     * if necessary.
     *
     * To simplify role handling we only keep track of the /last/ pending
     * role reply send to the switch. If multiple requests are pending and
     * we receive replies for earlier requests we ignore them. However, this
     * way of handling pending requests implies that we could wait forever if
     * a new request is submitted before the timeout triggers. If necessary
     * we could work around that though.
     */
    private class RoleChanger {
        // indicates that a request is currently pending
        // needs to be volatile to allow correct double-check idiom
        private volatile boolean requestPending;
        // the transaction Id of the pending request
        private int pendingXid;
        // the role that's pending
        private Role pendingRole;
        // system time in MS when we send the request
        private long roleSubmitTime;
        // the timeout to use
        private final long roleTimeoutMs;
        // the expectation set by the caller for the returned role
        private RoleRecvStatus expectation;

        public RoleChanger(long roleTimeoutMs) {
            this.requestPending = false;
            this.roleSubmitTime = 0;
            this.pendingXid = -1;
            this.pendingRole = null;
            this.roleTimeoutMs = roleTimeoutMs;
            this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
        }

        /**
         * Send NX role request message to the switch requesting the specified
         * role.
         *
         * @param sw switch to send the role request message to
         * @param role role to request
         */
        private int sendNxRoleRequest(Role role) throws IOException {
            // Convert the role enum to the appropriate role to send
            OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER;
            switch (role) {
            case MASTER:
                roleToSend = OFNiciraControllerRole.ROLE_MASTER;
                break;
            case SLAVE:
            case EQUAL:
            default:
                // ensuring that the only two roles sent to 1.0 switches with
                // Nicira role support, are MASTER and SLAVE
                roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
                log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
            }
            int xid = sw.getNextTransactionId();
            OFExperimenter roleRequest = factory10
                    .buildNiciraControllerRoleRequest()
                    .setXid(xid)
                    .setRole(roleToSend)
                    .build();
            sw.write(Collections.<OFMessage>singletonList(roleRequest));
            return xid;
        }

        private int sendOF13RoleRequest(Role role) throws IOException {
            // Convert the role enum to the appropriate role to send
            OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE;
            switch (role) {
            case EQUAL:
                roleToSend = OFControllerRole.ROLE_EQUAL;
                break;
            case MASTER:
                roleToSend = OFControllerRole.ROLE_MASTER;
                break;
            case SLAVE:
                roleToSend = OFControllerRole.ROLE_SLAVE;
                break;
            default:
                log.warn("Sending default role.noChange to switch {}."
                        + " Should only be used for queries.", sw);
            }

            int xid = sw.getNextTransactionId();
            OFRoleRequest rrm = factory13
                    .buildRoleRequest()
                    .setRole(roleToSend)
                    .setXid(xid)
                    .setGenerationId(sw.getNextGenerationId())
                    .build();
            sw.write(rrm);
            return xid;
        }

        /**
         * Send a role request with the given role to the switch and update
         * the pending request and timestamp.
         * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
         * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
         * in the IOFSwitch driver. If not supported, this method sends nothing
         * and returns 'false'. The caller should take appropriate action.
         *
         * One other optimization we do here is that for OF1.0 switches with
         * Nicira role message support, we force the Role.EQUAL to become
         * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
         * We cannot expect it to behave like SLAVE. We don't have this problem with
         * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
         * SLAVE behavior by using ASYNC messages.
         *
         * @param role
         * @throws IOException
         * @returns false if and only if the switch does not support role-request
         * messages, according to the switch driver; true otherwise.
         */
        synchronized boolean sendRoleRequest(Role role, RoleRecvStatus exp)
                throws IOException {
            this.expectation = exp;

            if (ofVersion == OFVersion.OF_10) {
                Boolean supportsNxRole = (Boolean)
                        sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE);
                if (!supportsNxRole) {
                    log.debug("Switch driver indicates no support for Nicira "
                            + "role request messages. Not sending ...");
                    state.handleUnsentRoleMessage(OFChannelHandler.this, role,
                            expectation);
                    return false;
                }
                // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
                // make Role.EQUAL become Role.SLAVE
                role = (role == Role.EQUAL) ? Role.SLAVE : role;
                pendingXid = sendNxRoleRequest(role);
                pendingRole = role;
                roleSubmitTime = System.currentTimeMillis();
                requestPending = true;
            } else {
                // OF1.3 switch, use OFPT_ROLE_REQUEST message
                pendingXid = sendOF13RoleRequest(role);
                pendingRole = role;
                roleSubmitTime = System.currentTimeMillis();
                requestPending = true;
            }
            return true;
        }

        /**
         * Deliver a received role reply.
         *
         * Check if a request is pending and if the received reply matches the
         * the expected pending reply (we check both role and xid) we set
         * the role for the switch/channel.
         *
         * If a request is pending but doesn't match the reply we ignore it, and
         * return
         *
         * If no request is pending we disconnect with a SwitchStateException
         *
         * @param RoleReplyInfo information about role-reply in format that
         *                      controller can understand.
         * @throws SwitchStateException if no request is pending
         */
        synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
                throws SwitchStateException {
            if (!requestPending) {
                Role currentRole = (sw != null) ? sw.getRole() : null;
                if (currentRole != null) {
                    if (currentRole == rri.getRole()) {
                        // Don't disconnect if the role reply we received is
                        // for the same role we are already in.
                        log.debug("Received unexpected RoleReply from "
                                + "Switch: {} in State: {}. "
                                + "Role in reply is same as current role of this "
                                + "controller for this sw. Ignoring ...",
                                getSwitchInfoString(), state.toString());
                        return RoleRecvStatus.OTHER_EXPECTATION;
                    } else {
                        String msg = String.format("Switch: [%s], State: [%s], "
                                + "received unexpected RoleReply[%s]. "
                                + "No roles are pending, and this controller's "
                                + "current role:[%s] does not match reply. "
                                + "Disconnecting switch ... ",
                                OFChannelHandler.this.getSwitchInfoString(),
                                OFChannelHandler.this.state.toString(),
                                rri, currentRole);
                        throw new SwitchStateException(msg);
                    }
                }
                log.debug("Received unexpected RoleReply {} from "
                        + "Switch: {} in State: {}. "
                        + "This controller has no current role for this sw. "
                        + "Ignoring ...", new Object[] {rri,
                                getSwitchInfoString(), state});
                return RoleRecvStatus.OTHER_EXPECTATION;
            }

            int xid = (int) rri.getXid();
            Role role = rri.getRole();
            // XXX S should check generation id meaningfully and other cases of expectations
            // U64 genId = rri.getGenId();

            if (pendingXid != xid) {
                log.debug("Received older role reply from " +
                        "switch {} ({}). Ignoring. " +
                        "Waiting for {}, xid={}",
                        new Object[] {getSwitchInfoString(), rri,
                        pendingRole, pendingXid });
                return RoleRecvStatus.OLD_REPLY;
            }

            if (pendingRole == role) {
                log.debug("Received role reply message from {} that matched "
                        + "expected role-reply {} with expectations {}",
                        new Object[] {getSwitchInfoString(), role, expectation});
                counters.roleReplyReceived.updateCounterWithFlush();
                //setSwitchRole(role, RoleRecvStatus.RECEIVED_REPLY); dont want to set state here
                if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
                        expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
                    return expectation;
                } else {
                    return RoleRecvStatus.OTHER_EXPECTATION;
                }
            }

            // if xids match but role's don't, perhaps its a query (OF1.3)
            if (expectation == RoleRecvStatus.REPLY_QUERY) {
                return expectation;
            }

            return RoleRecvStatus.OTHER_EXPECTATION;
        }

        /**
         * Called if we receive an  error message. If the xid matches the
         * pending request we handle it otherwise we ignore it.
         *
         * Note: since we only keep the last pending request we might get
         * error messages for earlier role requests that we won't be able
         * to handle
         */
        synchronized RoleRecvStatus deliverError(OFErrorMsg error)
                throws SwitchStateException {
            if (!requestPending) {
                log.debug("Received an error msg from sw {}, but no pending "
                        + "requests in role-changer; not handling ...",
                        getSwitchInfoString());
                return RoleRecvStatus.OTHER_EXPECTATION;
            }
            if (pendingXid != error.getXid()) {
                if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
                    log.debug("Received an error msg from sw {} for a role request,"
                            + " but not for pending request in role-changer; "
                            + " ignoring error {} ...",
                            getSwitchInfoString(), error);
                }
                return RoleRecvStatus.OTHER_EXPECTATION;
            }
            // it is an error related to a currently pending role request message
            if (error.getErrType() == OFErrorType.BAD_REQUEST) {
                counters.roleReplyErrorUnsupported.updateCounterWithFlush();
                log.error("Received a error msg {} from sw {} in state {} for "
                        + "pending role request {}. Switch driver indicates "
                        + "role-messaging is supported. Possible issues in "
                        + "switch driver configuration?", new Object[] {
                                ((OFBadRequestErrorMsg) error).toString(),
                                getSwitchInfoString(), state, pendingRole
                        });
                return RoleRecvStatus.UNSUPPORTED;
            }

            if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
                OFRoleRequestFailedErrorMsg rrerr =
                        (OFRoleRequestFailedErrorMsg) error;
                switch (rrerr.getCode()) {
                case BAD_ROLE:
                    // switch says that current-role-req has bad role?
                    // for now we disconnect
                    // fall-thru
                case STALE:
                    // switch says that current-role-req has stale gen-id?
                    // for now we disconnect
                    // fall-thru
                case UNSUP:
                    // switch says that current-role-req has role that
                    // cannot be supported? for now we disconnect
                    String msgx = String.format("Switch: [%s], State: [%s], "
                            + "received Error to for pending role request [%s]. "
                            + "Error:[%s]. Disconnecting switch ... ",
                            OFChannelHandler.this.getSwitchInfoString(),
                            OFChannelHandler.this.state.toString(),
                            pendingRole, rrerr);
                    throw new SwitchStateException(msgx);
                default:
                    break;
                }
            }

            // This error message was for a role request message but we dont know
            // how to handle errors for nicira role request messages
            return RoleRecvStatus.OTHER_EXPECTATION;
        }

        /**
         * Check if a pending role request has timed out.
         */
        void checkTimeout() {
            if (!requestPending) {
                return;
            }
            synchronized (this) {
                if (!requestPending) {
                    return;
                }
                long now = System.currentTimeMillis();
                if (now - roleSubmitTime > roleTimeoutMs) {
                    // timeout triggered.
                    counters.roleReplyTimeout.updateCounterWithFlush();
                    //setSwitchRole(pendingRole, RoleRecvStatus.NO_REPLY);
                    // XXX S come back to this
                }
            }
        }

    }

    //*************************
    //  Channel State Machine
    //*************************

    /**
     * The state machine for handling the switch/channel state. All state
     * transitions should happen from within the state machine (and not from other
     * parts of the code)
     */
    enum ChannelState {
        /**
         * Initial state before channel is connected.
         */
        INIT(false) {
            @Override
            void processOFMessage(OFChannelHandler h, OFMessage m)
                    throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }

            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws IOException {
                // need to implement since its abstract but it will never
                // be called
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException {
                unhandledMessageReceived(h, m);
            }
        },

        /**
         * We send a OF 1.3 HELLO to the switch and wait for a Hello from the switch.
         * Once we receive the reply, we decide on OF 1.3 or 1.0 switch - no other
         * protocol version is accepted.
         * We send an OFFeaturesRequest depending on the protocol version selected
         * Next state is WAIT_FEATURES_REPLY
         */
        WAIT_HELLO(false) {
            @Override
            void processOFHello(OFChannelHandler h, OFHello m)
                    throws IOException {
                // TODO We could check for the optional bitmap, but for now
                // we are just checking the version number.
                if (m.getVersion() == OFVersion.OF_13) {
                    log.info("Received {} Hello from {}", m.getVersion(),
                            h.channel.getRemoteAddress());
                    h.ofVersion = OFVersion.OF_13;
                } else if (m.getVersion() == OFVersion.OF_10) {
                    log.info("Received {} Hello from {} - switching to OF "
                            + "version 1.0", m.getVersion(),
                            h.channel.getRemoteAddress());
                    h.ofVersion = OFVersion.OF_10;
                } else {
                    log.error("Received Hello of version {} from switch at {}. "
                            + "This controller works with OF1.0 and OF1.3 "
                            + "switches. Disconnecting switch ...",
                            m.getVersion(), h.channel.getRemoteAddress());
                    h.channel.disconnect();
                    return;
                }
                h.sendHandshakeFeaturesRequestMessage();
                h.setState(WAIT_FEATURES_REPLY);
            }
            @Override
            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                    throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }
            @Override
            void processOFStatisticsReply(OFChannelHandler h,
                    OFStatsReply  m)
                            throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }
            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m) {
                logErrorDisconnect(h, m);
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException {
                unhandledMessageReceived(h, m);
            }
        },


        /**
         * We are waiting for a features reply message. Once we receive it, the
         * behavior depends on whether this is a 1.0 or 1.3 switch. For 1.0,
         * we send a SetConfig request, barrier, and GetConfig request and the
         * next state is WAIT_CONFIG_REPLY. For 1.3, we send a Port description
         * request and the next state is WAIT_PORT_DESC_REPLY.
         */
        WAIT_FEATURES_REPLY(false) {
            @Override
            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                    throws IOException {
                h.thisdpid = m.getDatapathId().getLong();
                log.info("Received features reply for switch at {} with dpid {}",
                        h.getSwitchInfoString(), h.thisdpid);
                //update the controller about this connected switch
                boolean success = h.controller.addConnectedSwitch(
                        h.thisdpid, h);
                if (!success) {
                    disconnectDuplicate(h);
                    return;
                }

                h.featuresReply = m; //temp store
                if (h.ofVersion == OFVersion.OF_10) {
                    h.sendHandshakeSetConfig();
                    h.setState(WAIT_CONFIG_REPLY);
                } else {
                    //version is 1.3, must get switchport information
                    h.sendHandshakeOFPortDescRequest();
                    h.setState(WAIT_PORT_DESC_REPLY);
                }
            }
            @Override
            void processOFStatisticsReply(OFChannelHandler h,
                    OFStatsReply  m)
                            throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }
            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m) {
                logErrorDisconnect(h, m);
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException {
                unhandledMessageReceived(h, m);
            }
        },

        /**
         * We are waiting for a description of the 1.3 switch ports.
         * Once received, we send a SetConfig request
         * Next State is WAIT_CONFIG_REPLY
         */
        WAIT_PORT_DESC_REPLY(false) {

            @Override
            void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
                    throws SwitchStateException {
                // Read port description
                if (m.getStatsType() != OFStatsType.PORT_DESC) {
                    log.warn("Expecting port description stats but received stats "
                            + "type {} from {}. Ignoring ...", m.getStatsType(),
                            h.channel.getRemoteAddress());
                    return;
                }
                if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
                    log.warn("Stats reply indicates more stats from sw {} for "
                            + "port description - not currently handled",
                            h.getSwitchInfoString());
                }
                h.portDescReply = (OFPortDescStatsReply) m; // temp store
                log.info("Received port desc reply for switch at {}",
                        h.getSwitchInfoString());
                try {
                    h.sendHandshakeSetConfig();
                } catch (IOException e) {
                    log.error("Unable to send setConfig after PortDescReply. "
                            + "Error: {}", e.getMessage());
                }
                h.setState(WAIT_CONFIG_REPLY);
            }

            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws IOException, SwitchStateException {
                logErrorDisconnect(h, m);

            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException, SwitchStateException {
                unhandledMessageReceived(h, m);

            }
        },

        /**
         * We are waiting for a config reply message. Once we receive it
         * we send a DescriptionStatsRequest to the switch.
         * Next state: WAIT_DESCRIPTION_STAT_REPLY
         */
        WAIT_CONFIG_REPLY(false) {
            @Override
            @LogMessageDocs({
                @LogMessageDoc(level = "WARN",
                        message = "Config Reply from {switch} has "
                                + "miss length set to {length}",
                                explanation = "The controller requires that the switch "
                                        + "use a miss length of 0xffff for correct "
                                        + "function",
                                        recommendation = "Use a different switch to ensure "
                                                + "correct function")
            })
            void processOFGetConfigReply(OFChannelHandler h, OFGetConfigReply m)
                    throws IOException {
                if (m.getMissSendLen() == 0xffff) {
                    log.trace("Config Reply from switch {} confirms "
                            + "miss length set to 0xffff",
                            h.getSwitchInfoString());
                } else {
                    // FIXME: we can't really deal with switches that don't send
                    // full packets. Shouldn't we drop the connection here?
                    log.warn("Config Reply from switch {} has"
                            + "miss length set to {}",
                            h.getSwitchInfoString(),
                            m.getMissSendLen());
                }
                h.sendHandshakeDescriptionStatsRequest();
                h.setState(WAIT_DESCRIPTION_STAT_REPLY);
            }

            @Override
            void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m) {
                // do nothing;
            }

            @Override
            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                    throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }
            @Override
            void processOFStatisticsReply(OFChannelHandler h,
                    OFStatsReply  m)
                            throws IOException, SwitchStateException {
                log.error("Received multipart(stats) message sub-type {}",
                        m.getStatsType());
                illegalMessageReceived(h, m);
            }

            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m) {
                logErrorDisconnect(h, m);
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException {
                h.pendingPortStatusMsg.add(m);
            }
        },


        /**
         * We are waiting for a OFDescriptionStat message from the switch.
         * Once we receive any stat message we try to parse it. If it's not
         * a description stats message we disconnect. If its the expected
         * description stats message, we:
         *    - use the switch driver to bind the switch and get an IOFSwitch instance
         *    - setup the IOFSwitch instance
         *    - add switch controller and send the initial role
         *      request to the switch.
         * Next state: WAIT_INITIAL_ROLE
         *      In the typical case, where switches support role request messages
         *      the next state is where we expect the role reply message.
         *      In the special case that where the switch does not support any kind
         *      of role request messages, we don't send a role message, but we do
         *      request mastership from the registry service. This controller
         *      should become master once we hear back from the registry service.
         * All following states will have a h.sw instance!
         */
        WAIT_DESCRIPTION_STAT_REPLY(false) {
            @LogMessageDoc(message = "Switch {switch info} bound to class "
                    + "{switch driver}, description {switch description}",
                    explanation = "The specified switch has been bound to "
                            + "a switch driver based on the switch description"
                            + "received from the switch")
            @Override
            void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
                    throws SwitchStateException {
                // Read description, if it has been updated
                if (m.getStatsType() != OFStatsType.DESC) {
                    log.warn("Expecting Description stats but received stats "
                            + "type {} from {}. Ignoring ...", m.getStatsType(),
                            h.channel.getRemoteAddress());
                    return;
                }
                log.info("Received switch description reply from switch at {}",
                        h.channel.getRemoteAddress());
                OFDescStatsReply drep = (OFDescStatsReply) m;
                // Here is where we differentiate between different kinds of switches
                h.sw = h.controller.getOFSwitchInstance(drep, h.ofVersion);
                // set switch information
                h.sw.setOFVersion(h.ofVersion);
                h.sw.setFeaturesReply(h.featuresReply);
                h.sw.setPortDescReply(h.portDescReply);
                h.sw.setConnected(true);
                h.sw.setChannel(h.channel);

                try {
                    h.sw.setDebugCounterService(h.controller.getDebugCounter());
                } catch (CounterException e) {
                    h.counters.switchCounterRegistrationFailed
                    .updateCounterNoFlush();
                    log.warn("Could not register counters for switch {} ",
                            h.getSwitchInfoString(), e);
                }

                log.info("Switch {} bound to class {}, description {}",
                        new Object[] {h.sw, h.sw.getClass(), drep });
                //Put switch in EQUAL mode until we hear back from the global registry
                log.debug("Setting new switch {} to EQUAL and sending Role request",
                        h.sw.getStringId());
                h.setSwitchRole(Role.EQUAL);
                try {
                    boolean supportsRRMsg = h.roleChanger.sendRoleRequest(Role.EQUAL,
                            RoleRecvStatus.MATCHED_CURRENT_ROLE);
                    if (!supportsRRMsg) {
                        log.warn("Switch {} does not support role request messages "
                                + "of any kind. No role messages were sent. "
                                + "This controller instance SHOULD become MASTER "
                                + "from the registry process. ",
                                h.getSwitchInfoString());
                    }
                    h.setState(WAIT_INITIAL_ROLE);
                    // request control of switch from global registry -
                    // necessary even if this is the only controller the
                    // switch is connected to.
                    h.controller.submitRegistryRequest(h.sw.getId());
                } catch (IOException e) {
                    log.error("Exception when sending role request: {} ",
                            e.getMessage());
                    // FIXME shouldn't we disconnect?
                }
            }

            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m) {
                logErrorDisconnect(h, m);
            }

            @Override
            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                    throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException {
                h.pendingPortStatusMsg.add(m);
            }
        },

        /**
         * We are waiting for a role reply message in response to a role request
         * sent after hearing back from the registry service -- OR -- we are
         * just waiting to hear back from the registry service in the case that
         * the switch does not support role messages. If completed successfully,
         * the controller's role for this switch will be set here.
         * Before we move to the state corresponding to the role, we allow the
         * switch specific driver to complete its configuration. This configuration
         * typically depends on the role the controller is playing for this switch.
         * And so we set the switch role (for 'this' controller) before we start
         * the driver-sub-handshake.
         * Next State: WAIT_SWITCH_DRIVER_SUB_HANDSHAKE
         */
        WAIT_INITIAL_ROLE(false) {
            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws SwitchStateException {
                // role changer will ignore the error if it isn't for it
                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
                if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
                    logError(h, m);
                }
            }

            @Override
            void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
                    throws IOException, SwitchStateException {
                Role role = extractNiciraRoleReply(h, m);
                // If role == null it means the vendor (experimenter) message
                // wasn't really a Nicira role reply. We ignore this case.
                if (role != null) {
                    RoleReplyInfo rri = new RoleReplyInfo(role, null, m.getXid());
                    RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
                    if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                        setRoleAndStartDriverHandshake(h, rri.getRole());
                    } // else do nothing - wait for the correct expected reply
                } else {
                    unhandledMessageReceived(h, m);
                }
            }

            @Override
            void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                    throws SwitchStateException, IOException {
                RoleReplyInfo rri = extractOFRoleReply(h, m);
                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                    setRoleAndStartDriverHandshake(h, rri.getRole());
                } // else do nothing - wait for the correct expected reply
            }

            @Override
            void handleUnsentRoleMessage(OFChannelHandler h, Role role,
                    RoleRecvStatus expectation) throws IOException {
                // typically this is triggered for a switch where role messages
                // are not supported - we confirm that the role being set is
                // master and move to the next state
                if (expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
                    if (role == Role.MASTER) {
                        setRoleAndStartDriverHandshake(h, role);
                    } else {
                        log.error("Expected MASTER role from registry for switch "
                                + "which has no support for role-messages."
                                + "Received {}. It is possible that this switch "
                                + "is connected to other controllers, in which "
                                + "case it should support role messages - not "
                                + "moving forward.", role);
                    }
                } // else do nothing - wait to hear back from registry

            }

            private void setRoleAndStartDriverHandshake(OFChannelHandler h,
                    Role role) throws IOException {
                h.setSwitchRole(role);
                h.sw.startDriverHandshake();
                if (h.sw.isDriverHandshakeComplete()) {
                    Role mySwitchRole = h.sw.getRole();
                    if (mySwitchRole == Role.MASTER) {
                        log.info("Switch-driver sub-handshake complete. "
                                + "Activating switch {} with Role: MASTER",
                                h.getSwitchInfoString());
                        handlePendingPortStatusMessages(h); //before activation
                        boolean success = h.controller.addActivatedMasterSwitch(
                                h.sw.getId(), h.sw);
                        if (!success) {
                            disconnectDuplicate(h);
                            return;
                        }
                        h.setState(MASTER);
                    } else {
                        log.info("Switch-driver sub-handshake complete. "
                                + "Activating switch {} with Role: EQUAL",
                                h.getSwitchInfoString());
                        handlePendingPortStatusMessages(h); //before activation
                        boolean success = h.controller.addActivatedEqualSwitch(
                                h.sw.getId(), h.sw);
                        if (!success) {
                            disconnectDuplicate(h);
                            return;
                        }
                        h.setState(EQUAL);
                    }
                } else {
                    h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
                }
            }

            @Override
            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                    throws IOException, SwitchStateException {
                illegalMessageReceived(h, m);
            }

            @Override
            void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
                    throws SwitchStateException {
                illegalMessageReceived(h, m);
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException, SwitchStateException {
                h.pendingPortStatusMsg.add(m);

            }
        },

        /**
         * We are waiting for the respective switch driver to complete its
         * configuration. Notice that we do not consider this to be part of the main
         * switch-controller handshake. But we do consider it as a step that comes
         * before we declare the switch as available to the controller.
         * Next State: depends on the role of this controller for this switch - either
         * MASTER or EQUAL.
         */
        WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(true) {

            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws IOException {
                // will never be called. We override processOFMessage
            }

            @Override
            void processOFMessage(OFChannelHandler h, OFMessage m)
                    throws IOException {
                if (m.getType() == OFType.ECHO_REQUEST) {
                    processOFEchoRequest(h, (OFEchoRequest) m);
                } else {
                    // FIXME: other message to handle here?
                    h.sw.processDriverHandshakeMessage(m);
                    if (h.sw.isDriverHandshakeComplete()) {
                        // consult the h.sw role and goto that state
                        Role mySwitchRole = h.sw.getRole();
                        if (mySwitchRole == Role.MASTER) {
                            log.info("Switch-driver sub-handshake complete. "
                                    + "Activating switch {} with Role: MASTER",
                                    h.getSwitchInfoString());
                            handlePendingPortStatusMessages(h); //before activation
                            boolean success = h.controller.addActivatedMasterSwitch(
                                    h.sw.getId(), h.sw);
                            if (!success) {
                                disconnectDuplicate(h);
                                return;
                            }
                            h.setState(MASTER);
                        } else {
                            log.info("Switch-driver sub-handshake complete. "
                                    + "Activating switch {} with Role: EQUAL",
                                    h.getSwitchInfoString());
                            handlePendingPortStatusMessages(h); //before activation
                            boolean success = h.controller.addActivatedEqualSwitch(
                                    h.sw.getId(), h.sw);
                            if (!success) {
                                disconnectDuplicate(h);
                                return;
                            }
                            h.setState(EQUAL);
                        }
                    }
                }
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException, SwitchStateException {
                h.pendingPortStatusMsg.add(m);
            }
        },


        /**
         * This controller is in MASTER role for this switch. We enter this state
         * after requesting and winning control from the global registry.
         * The main handshake as well as the switch-driver sub-handshake
         * is complete at this point.
         * // XXX S reconsider below
         * In the (near) future we may deterministically assign controllers to
         * switches at startup.
         * We only leave this state if the switch disconnects or
         * if we send a role request for SLAVE /and/ receive the role reply for
         * SLAVE.
         */
        MASTER(true) {
            @LogMessageDoc(level = "WARN",
                    message = "Received permission error from switch {} while"
                            + "being master. Reasserting master role.",
                            explanation = "The switch has denied an operation likely "
                                    + "indicating inconsistent controller roles",
                                    recommendation = "This situation can occurs transiently during role"
                                            + " changes. If, however, the condition persists or happens"
                                            + " frequently this indicates a role inconsistency. "
                                            + LogMessageDoc.CHECK_CONTROLLER)
            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws IOException, SwitchStateException {
                // first check if the error msg is in response to a role-request message
                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
                if (rrstatus != RoleRecvStatus.OTHER_EXPECTATION) {
                    // rolechanger has handled the error message - we are done
                    return;
                }

                // if we get here, then the error message is for something else
                if (m.getErrType() == OFErrorType.BAD_REQUEST &&
                        ((OFBadRequestErrorMsg) m).getCode() ==
                        OFBadRequestCode.EPERM) {
                    // We are the master controller and the switch returned
                    // a permission error. This is a likely indicator that
                    // the switch thinks we are slave. Reassert our
                    // role
                    // FIXME: this could be really bad during role transitions
                    // if two controllers are master (even if its only for
                    // a brief period). We might need to see if these errors
                    // persist before we reassert
                    h.counters.epermErrorWhileSwitchIsMaster.updateCounterWithFlush();
                    log.warn("Received permission error from switch {} while" +
                            "being master. Reasserting master role.",
                            h.getSwitchInfoString());
                    //h.controller.reassertRole(h, Role.MASTER);
                    // XXX S reassert in role changer or reconsider if all this
                    // stuff is really needed
                } else if (m.getErrType() == OFErrorType.FLOW_MOD_FAILED &&
                        ((OFFlowModFailedErrorMsg) m).getCode() ==
                        OFFlowModFailedCode.ALL_TABLES_FULL) {
                    h.sw.setTableFull(true);
                } else {
                    logError(h, m);
                }
                h.dispatchMessage(m);
            }

            @Override
            void processOFStatisticsReply(OFChannelHandler h,
                    OFStatsReply m) {
                h.sw.deliverStatisticsReply(m);
            }

            @Override
            void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
                    throws IOException, SwitchStateException {
                Role role = extractNiciraRoleReply(h, m);
                if (role == null) {
                    // The message wasn't really a Nicira role reply. We just
                    // dispatch it to the OFMessage listeners in this case.
                    h.dispatchMessage(m);
                    return;
                }

                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
                        new RoleReplyInfo(role, null, m.getXid()));
                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                    checkAndSetRoleTransition(h, role);
                }
            }

            @Override
            void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                    throws SwitchStateException, IOException {
                RoleReplyInfo rri = extractOFRoleReply(h, m);
                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                    checkAndSetRoleTransition(h, rri.getRole());
                }
            }

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException, SwitchStateException {
                handlePortStatusMessage(h, m, true);
                h.dispatchMessage(m);
            }

            @Override
            void processOFPacketIn(OFChannelHandler h, OFPacketIn m)
                    throws IOException {
                h.dispatchMessage(m);
            }

            @Override
            void processOFFlowRemoved(OFChannelHandler h,
                    OFFlowRemoved m) throws IOException {
                h.dispatchMessage(m);
            }

            @Override
            void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m)
                    throws IOException {
                h.dispatchMessage(m);
            }

        },

        /**
         * This controller is in EQUAL role for this switch. We enter this state
         * after some /other/ controller instance wins mastership-role over this
         * switch. The EQUAL role can be considered the same as the SLAVE role
         * if this controller does NOT send commands or packets to the switch.
         * This should always be true for OF1.0 switches. XXX S need to enforce.
         *
         * For OF1.3 switches, choosing this state as EQUAL instead of SLAVE,
         * gives us the flexibility that if an app wants to send commands/packets
         * to switches, it can, even thought it is running on a controller instance
         * that is not in a MASTER role for this switch. Of course, it is the job
         * of the app to ensure that commands/packets sent by this (EQUAL) controller
         * instance does not clash/conflict with commands/packets sent by the MASTER
         * controller for this switch. Neither the controller instances, nor the
         * switch provides any kind of resolution mechanism should conflicts occur.
         */
        EQUAL(true) {
            @Override
            void processOFError(OFChannelHandler h, OFErrorMsg m)
                    throws IOException, SwitchStateException {
                // role changer will ignore the error if it isn't for it
                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
                if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
                    logError(h, m);
                    h.dispatchMessage(m);
                }
            }

            @Override
            void processOFStatisticsReply(OFChannelHandler h,
                    OFStatsReply m) {
                h.sw.deliverStatisticsReply(m);
            }

            @Override
            void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
                    throws IOException, SwitchStateException {
                Role role = extractNiciraRoleReply(h, m);
                // If role == null it means the message wasn't really a
                // Nicira role reply. We ignore it in this state.
                if (role != null) {
                    RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
                            new RoleReplyInfo(role, null, m.getXid()));
                    if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                        checkAndSetRoleTransition(h, role);
                    }
                } else {
                    unhandledMessageReceived(h, m);
                }
            }

            @Override
            void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                    throws SwitchStateException, IOException {
                RoleReplyInfo rri = extractOFRoleReply(h, m);
                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
                    checkAndSetRoleTransition(h, rri.getRole());
                }
            }

            // XXX S needs more handlers for 1.3 switches in equal role

            @Override
            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                    throws IOException, SwitchStateException {
                handlePortStatusMessage(h, m, true);
            }

            @Override
            @LogMessageDoc(level = "WARN",
            message = "Received PacketIn from switch {} while "
                    + "being slave. Reasserting slave role.",
                    explanation = "The switch has receive a PacketIn despite being "
                            + "in slave role indicating inconsistent controller roles",
                            recommendation = "This situation can occurs transiently during role"
                                    + " changes. If, however, the condition persists or happens"
                                    + " frequently this indicates a role inconsistency. "
                                    + LogMessageDoc.CHECK_CONTROLLER)
            void processOFPacketIn(OFChannelHandler h, OFPacketIn m) throws IOException {
                // we don't expect packetIn while slave, reassert we are slave
                h.counters.packetInWhileSwitchIsSlave.updateCounterNoFlush();
                log.warn("Received PacketIn from switch {} while" +
                        "being slave. Reasserting slave role.", h.sw);
                //h.controller.reassertRole(h, Role.SLAVE);
                // XXX reassert in role changer
            }
        };

        private final boolean handshakeComplete;
        ChannelState(boolean handshakeComplete) {
            this.handshakeComplete = handshakeComplete;
        }

        /**
         * Is this a state in which the handshake has completed?
         * @return true if the handshake is complete
         */
        public boolean isHandshakeComplete() {
            return handshakeComplete;
        }

        /**
         * Get a string specifying the switch connection, state, and
         * message received. To be used as message for SwitchStateException
         * or log messages
         * @param h The channel handler (to get switch information_
         * @param m The OFMessage that has just been received
         * @param details A string giving more details about the exact nature
         * of the problem.
         * @return
         */
        // needs to be protected because enum members are actually subclasses
        protected String getSwitchStateMessage(OFChannelHandler h,
                OFMessage m,
                String details) {
            return String.format("Switch: [%s], State: [%s], received: [%s]"
                    + ", details: %s",
                    h.getSwitchInfoString(),
                    this.toString(),
                    m.getType().toString(),
                    details);
        }

        /**
         * We have an OFMessage we didn't expect given the current state and
         * we want to treat this as an error.
         * We currently throw an exception that will terminate the connection
         * However, we could be more forgiving
         * @param h the channel handler that received the message
         * @param m the message
         * @throws SwitchStateException
         * @throws SwitchStateExeption we always through the execption
         */
        // needs to be protected because enum members are acutally subclasses
        protected void illegalMessageReceived(OFChannelHandler h, OFMessage m)
                throws SwitchStateException {
            String msg = getSwitchStateMessage(h, m,
                    "Switch should never send this message in the current state");
            throw new SwitchStateException(msg);

        }

        /**
         * We have an OFMessage we didn't expect given the current state and
         * we want to ignore the message.
         * @param h the channel handler the received the message
         * @param m the message
         */
        protected void unhandledMessageReceived(OFChannelHandler h,
                OFMessage m) {
            h.counters.unhandledMessage.updateCounterNoFlush();
            if (log.isDebugEnabled()) {
                String msg = getSwitchStateMessage(h, m,
                        "Ignoring unexpected message");
                log.debug(msg);
            }
        }

        /**
         * Log an OpenFlow error message from a switch.
         * @param sw The switch that sent the error
         * @param error The error message
         */
        @LogMessageDoc(level = "ERROR",
                message = "Error {error type} {error code} from {switch} "
                        + "in state {state}",
                        explanation = "The switch responded with an unexpected error"
                                + "to an OpenFlow message from the controller",
                                recommendation = "This could indicate improper network operation. "
                                        + "If the problem persists restarting the switch and "
                                        + "controller may help."
                )
        protected void logError(OFChannelHandler h, OFErrorMsg error) {
            log.error("{} from switch {} in state {}",
                    new Object[] {
                    error,
                    h.getSwitchInfoString(),
                    this.toString()});
        }

        /**
         * Log an OpenFlow error message from a switch and disconnect the
         * channel.
         *
         * @param h the IO channel for this switch.
         * @param error The error message
         */
        protected void logErrorDisconnect(OFChannelHandler h, OFErrorMsg error) {
            logError(h, error);
            h.channel.disconnect();
        }

        /**
         * log an error message for a duplicate dpid and disconnect this channel.
         * @param h the IO channel for this switch.
         */
        protected void disconnectDuplicate(OFChannelHandler h) {
            log.error("Duplicated dpid or incompleted cleanup - "
                    + "disconnecting channel {}", h.getSwitchInfoString());
            h.duplicateDpidFound = Boolean.TRUE;
            h.channel.disconnect();
        }

        /**
         * Extract the role from an OFVendor message.
         *
         * Extract the role from an OFVendor message if the message is a
         * Nicira role reply. Otherwise return null.
         *
         * @param h The channel handler receiving the message
         * @param vendorMessage The vendor message to parse.
         * @return The role in the message if the message is a Nicira role
         * reply, null otherwise.
         * @throws SwitchStateException If the message is a Nicira role reply
         * but the numeric role value is unknown.
         */
        protected Role extractNiciraRoleReply(OFChannelHandler h,
                OFExperimenter experimenterMsg) throws SwitchStateException {
            int vendor = (int) experimenterMsg.getExperimenter();
            if (vendor != 0x2320) {
                return null;
            }
            OFNiciraControllerRoleReply nrr =
                    (OFNiciraControllerRoleReply) experimenterMsg;

            Role role = null;
            OFNiciraControllerRole ncr = nrr.getRole();
            switch(ncr) {
            case ROLE_MASTER:
                role = Role.MASTER;
                break;
            case ROLE_OTHER:
                role = Role.EQUAL;
                break;
            case ROLE_SLAVE:
                role = Role.SLAVE;
                break;
            default: //handled below
            }

            if (role == null) {
                String msg = String.format("Switch: [%s], State: [%s], "
                        + "received NX_ROLE_REPLY with invalid role "
                        + "value %s",
                        h.getSwitchInfoString(),
                        this.toString(),
                        nrr.getRole());
                throw new SwitchStateException(msg);
            }
            return role;
        }

        /**
         * Helper class returns role reply information in the format understood
         * by the controller.
         */
        protected static class RoleReplyInfo {
            private Role role;
            private U64 genId;
            private long xid;

            RoleReplyInfo(Role role, U64 genId, long xid) {
                this.role = role;
                this.genId = genId;
                this.xid = xid;
            }
            public Role getRole() { return role; }
            public U64 getGenId() { return genId; }
            public long getXid() { return xid; }
            @Override
            public String toString() {
                return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
            }
        }

        /**
         * Extract the role information from an OF1.3 Role Reply Message.
         * @param h
         * @param rrmsg
         * @return RoleReplyInfo object
         * @throws SwitchStateException
         */
        protected RoleReplyInfo extractOFRoleReply(OFChannelHandler h,
                OFRoleReply rrmsg) throws SwitchStateException {
            OFControllerRole cr = rrmsg.getRole();
            Role role = null;
            switch(cr) {
            case ROLE_EQUAL:
                role = Role.EQUAL;
                break;
            case ROLE_MASTER:
                role = Role.MASTER;
                break;
            case ROLE_SLAVE:
                role = Role.SLAVE;
                break;
            case ROLE_NOCHANGE: // switch should send current role
            default:
                String msg = String.format("Unknown controller role %s "
                        + "received from switch %s", cr, h.sw);
                throw new SwitchStateException(msg);
            }

            return new RoleReplyInfo(role, rrmsg.getGenerationId(), rrmsg.getXid());
        }

        /**
         * Handles all pending port status messages before a switch is declared
         * activated in MASTER or EQUAL role. Note that since this handling
         * precedes the activation (and therefore notification to IOFSwitchListerners)
         * the changes to ports will already be visible once the switch is
         * activated. As a result, no notifications are sent out for these
         * pending portStatus messages.
         * @param h
         * @throws SwitchStateException
         */
        protected void handlePendingPortStatusMessages(OFChannelHandler h) {
            try {
                handlePendingPortStatusMessages(h, 0);
            } catch (SwitchStateException e) {
                log.error(e.getMessage());
            }
        }

        private void handlePendingPortStatusMessages(OFChannelHandler h, int index)
                throws SwitchStateException {
            if (h.sw == null) {
                String msg = "State machine error: switch is null. Should never " +
                        "happen";
                throw new SwitchStateException(msg);
            }
            ArrayList<OFPortStatus> temp  = new ArrayList<OFPortStatus>();
            for (OFPortStatus ps: h.pendingPortStatusMsg) {
                temp.add(ps);
                handlePortStatusMessage(h, ps, false);
            }
            temp.clear();
            // expensive but ok - we don't expect too many port-status messages
            // note that we cannot use clear(), because of the reasons below
            h.pendingPortStatusMsg.removeAll(temp);
            // the iterator above takes a snapshot of the list - so while we were
            // dealing with the pending port-status messages, we could have received
            // newer ones. Handle them recursively, but break the recursion after
            // five steps to avoid an attack.
            if (!h.pendingPortStatusMsg.isEmpty() && ++index < 5) {
                handlePendingPortStatusMessages(h, index);
            }
        }

        /**
         * Handle a port status message.
         *
         * Handle a port status message by updating the port maps in the
         * IOFSwitch instance and notifying Controller about the change so
         * it can dispatch a switch update.
         *
         * @param h The OFChannelHhandler that received the message
         * @param m The PortStatus message we received
         * @param doNotify if true switch port changed events will be
         * dispatched
         * @throws SwitchStateException
         *
         */
        protected void handlePortStatusMessage(OFChannelHandler h, OFPortStatus m,
                boolean doNotify) throws SwitchStateException {
            if (h.sw == null) {
                String msg = getSwitchStateMessage(h, m,
                        "State machine error: switch is null. Should never " +
                        "happen");
                throw new SwitchStateException(msg);
            }

            Collection<PortChangeEvent> changes = h.sw.processOFPortStatus(m);
            if (doNotify) {
                for (PortChangeEvent ev: changes) {
                    h.controller.notifyPortChanged(h.sw.getId(), ev.port, ev.type);
                }
            }
        }

        /**
         * Checks if the role received (from the role-reply msg) is different
         * from the existing role in the IOFSwitch object for this controller.
         * If so, it transitions the controller to the new role. Note that
         * the caller should have already verified that the role-reply msg
         * received was in response to a role-request msg sent out by this
         * controller after hearing from the registry service.
         *
         * @param h the ChannelHandler that received the message
         * @param role the role in the recieved role reply message
         */
        protected void checkAndSetRoleTransition(OFChannelHandler h, Role role) {
            // we received a role-reply in response to a role message
            // sent after hearing from the registry service. It is
            // possible that the role of this controller instance for
            // this switch has changed:
            // for 1.0 switch: from MASTER to SLAVE
            // for 1.3 switch: from MASTER to EQUAL
            if ((h.sw.getRole() == Role.MASTER && role == Role.SLAVE) ||
                    (h.sw.getRole() == Role.MASTER && role == Role.EQUAL)) {
                // the mastership has changed
                h.sw.setRole(role);
                h.setState(EQUAL);
                h.controller.transitionToEqualSwitch(h.sw.getId());
                return;
            }

            // or for both 1.0 and 1.3 switches from EQUAL to MASTER.
            // note that for 1.0, even though we mean SLAVE,
            // internally we call the role EQUAL.
            if (h.sw.getRole() == Role.EQUAL && role == Role.MASTER) {
                // the mastership has changed
                h.sw.setRole(role);
                h.setState(MASTER);
                h.controller.transitionToMasterSwitch(h.sw.getId());
                return;
            }
        }

        /**
         * Process an OF message received on the channel and
         * update state accordingly.
         *
         * The main "event" of the state machine. Process the received message,
         * send follow up message if required and update state if required.
         *
         * Switches on the message type and calls more specific event handlers
         * for each individual OF message type. If we receive a message that
         * is supposed to be sent from a controller to a switch we throw
         * a SwitchStateExeption.
         *
         * The more specific handlers can also throw SwitchStateExceptions
         *
         * @param h The OFChannelHandler that received the message
         * @param m The message we received.
         * @throws SwitchStateException
         * @throws IOException
         */
        void processOFMessage(OFChannelHandler h, OFMessage m)
                throws IOException, SwitchStateException {
            h.roleChanger.checkTimeout();
            switch(m.getType()) {
            case HELLO:
                processOFHello(h, (OFHello) m);
                break;
            case BARRIER_REPLY:
                processOFBarrierReply(h, (OFBarrierReply) m);
                break;
            case ECHO_REPLY:
                processOFEchoReply(h, (OFEchoReply) m);
                break;
            case ECHO_REQUEST:
                processOFEchoRequest(h, (OFEchoRequest) m);
                break;
            case ERROR:
                processOFError(h, (OFErrorMsg) m);
                break;
            case FEATURES_REPLY:
                processOFFeaturesReply(h, (OFFeaturesReply) m);
                break;
            case FLOW_REMOVED:
                processOFFlowRemoved(h, (OFFlowRemoved) m);
                break;
            case GET_CONFIG_REPLY:
                processOFGetConfigReply(h, (OFGetConfigReply) m);
                break;
            case PACKET_IN:
                processOFPacketIn(h, (OFPacketIn) m);
                break;
            case PORT_STATUS:
                processOFPortStatus(h, (OFPortStatus) m);
                break;
            case QUEUE_GET_CONFIG_REPLY:
                processOFQueueGetConfigReply(h, (OFQueueGetConfigReply) m);
                break;
            case STATS_REPLY: // multipart_reply in 1.3
            processOFStatisticsReply(h, (OFStatsReply) m);
            break;
            case EXPERIMENTER:
                processOFExperimenter(h, (OFExperimenter) m);
                break;
            case ROLE_REPLY:
                processOFRoleReply(h, (OFRoleReply) m);
                break;
            case GET_ASYNC_REPLY:
                processOFGetAsyncReply(h, (OFAsyncGetReply) m);
                break;

                // The following messages are sent to switches. The controller
                // should never receive them
            case SET_CONFIG:
            case GET_CONFIG_REQUEST:
            case PACKET_OUT:
            case PORT_MOD:
            case QUEUE_GET_CONFIG_REQUEST:
            case BARRIER_REQUEST:
            case STATS_REQUEST: // multipart request in 1.3
            case FEATURES_REQUEST:
            case FLOW_MOD:
            case GROUP_MOD:
            case TABLE_MOD:
            case GET_ASYNC_REQUEST:
            case SET_ASYNC:
            case METER_MOD:
            default:
                illegalMessageReceived(h, m);
                break;
            }
        }

        /*-----------------------------------------------------------------
         * Default implementation for message handlers in any state.
         *
         * Individual states must override these if they want a behavior
         * that differs from the default.
         *
         * In general, these handlers simply ignore the message and do
         * nothing.
         *
         * There are some exceptions though, since some messages really
         * are handled the same way in every state (e.g., ECHO_REQUST) or
         * that are only valid in a single state (e.g., HELLO, GET_CONFIG_REPLY
         -----------------------------------------------------------------*/

        void processOFHello(OFChannelHandler h, OFHello m)
                throws IOException, SwitchStateException {
            // we only expect hello in the WAIT_HELLO state
            illegalMessageReceived(h, m);
        }

        void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m)
                throws IOException {
            // Silently ignore.
        }

        void processOFEchoRequest(OFChannelHandler h, OFEchoRequest m)
                throws IOException {
            if (h.ofVersion == null) {
                log.error("No OF version set for {}. Not sending Echo REPLY",
                        h.channel.getRemoteAddress());
                return;
            }
            OFFactory factory = (h.ofVersion == OFVersion.OF_13) ?
                    h.controller.getOFMessageFactory13() : h.controller.getOFMessageFactory10();
            OFEchoReply reply = factory
                    .buildEchoReply()
                    .setXid(m.getXid())
                    .setData(m.getData())
                    .build();
            h.channel.write(Collections.singletonList(reply));
        }

        void processOFEchoReply(OFChannelHandler h, OFEchoReply m)
                throws IOException {
            // Do nothing with EchoReplies !!
        }

        // no default implementation for OFError
        // every state must override it
        abstract void processOFError(OFChannelHandler h, OFErrorMsg m)
                throws IOException, SwitchStateException;


        void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
                throws IOException, SwitchStateException {
            unhandledMessageReceived(h, m);
        }

        void processOFFlowRemoved(OFChannelHandler h, OFFlowRemoved m)
                throws IOException {
            unhandledMessageReceived(h, m);
        }

        void processOFGetConfigReply(OFChannelHandler h, OFGetConfigReply m)
                throws IOException, SwitchStateException {
            // we only expect config replies in the WAIT_CONFIG_REPLY state
            illegalMessageReceived(h, m);
        }

        void processOFPacketIn(OFChannelHandler h, OFPacketIn m)
                throws IOException {
            unhandledMessageReceived(h, m);
        }

        // no default implementation. Every state needs to handle it.
        abstract void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
                throws IOException, SwitchStateException;

        void processOFQueueGetConfigReply(OFChannelHandler h,
                OFQueueGetConfigReply m)
                        throws IOException {
            unhandledMessageReceived(h, m);
        }

        void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
                throws IOException, SwitchStateException {
            unhandledMessageReceived(h, m);
        }

        void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
                throws IOException, SwitchStateException {
            // TODO: it might make sense to parse the vendor message here
            // into the known vendor messages we support and then call more
            // specific event handlers
            unhandledMessageReceived(h, m);
        }

        void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                throws SwitchStateException, IOException {
            unhandledMessageReceived(h, m);
        }

        void processOFGetAsyncReply(OFChannelHandler h,
                OFAsyncGetReply m) {
            unhandledMessageReceived(h, m);
        }

        void handleUnsentRoleMessage(OFChannelHandler h, Role role,
                RoleRecvStatus expectation) throws IOException {
            // do nothing in most states
        }
    }



    //*************************
    //  Channel handler methods
    //*************************

    @Override
    @LogMessageDoc(message = "New switch connection from {ip address}",
    explanation = "A new switch has connected from the "
            + "specified IP address")
    public void channelConnected(ChannelHandlerContext ctx,
            ChannelStateEvent e) throws Exception {
        counters.switchConnected.updateCounterWithFlush();
        channel = e.getChannel();
        log.info("New switch connection from {}",
                channel.getRemoteAddress());
        sendHandshakeHelloMessage();
        setState(ChannelState.WAIT_HELLO);
    }

    @Override
    @LogMessageDoc(message = "Disconnected switch {switch information}",
    explanation = "The specified switch has disconnected.")
    public void channelDisconnected(ChannelHandlerContext ctx,
            ChannelStateEvent e) throws Exception {
        log.info("Switch disconnected callback for sw:{}. Cleaning up ...",
                getSwitchInfoString());
        if (thisdpid != 0) {
            if (!duplicateDpidFound) {
                // if the disconnected switch (on this ChannelHandler)
                // was not one with a duplicate-dpid, it is safe to remove all
                // state for it at the controller. Notice that if the disconnected
                // switch was a duplicate-dpid, calling the method below would clear
                // all state for the original switch (with the same dpid),
                // which we obviously don't want.
                controller.removeConnectedSwitch(thisdpid);
            } else {
                // A duplicate was disconnected on this ChannelHandler,
                // this is the same switch reconnecting, but the original state was
                // not cleaned up - XXX check liveness of original ChannelHandler
                duplicateDpidFound = Boolean.FALSE;
            }
        } else {
            log.warn("no dpid in channelHandler registered for "
                    + "disconnected switch {}", getSwitchInfoString());
        }
    }

    @Override
    @LogMessageDocs({
        @LogMessageDoc(level = "ERROR",
                message = "Disconnecting switch {switch} due to read timeout",
                explanation = "The connected switch has failed to send any "
                        + "messages or respond to echo requests",
                recommendation = LogMessageDoc.CHECK_SWITCH),
                        @LogMessageDoc(level = "ERROR",
                message = "Disconnecting switch {switch}: failed to "
                        + "complete handshake",
                explanation = "The switch did not respond correctly "
                        + "to handshake messages",
                recommendation = LogMessageDoc.CHECK_SWITCH),
        @LogMessageDoc(level = "ERROR",
                message = "Disconnecting switch {switch} due to IO Error: {}",
                explanation = "There was an error communicating with the switch",
                recommendation = LogMessageDoc.CHECK_SWITCH),
        @LogMessageDoc(level = "ERROR",
                message = "Disconnecting switch {switch} due to switch "
                        + "state error: {error}",
                explanation = "The switch sent an unexpected message",
                recommendation = LogMessageDoc.CHECK_SWITCH),
        @LogMessageDoc(level = "ERROR",
                message = "Disconnecting switch {switch} due to "
                          + "message parse failure",
                explanation = "Could not parse a message from the switch",
                recommendation = LogMessageDoc.CHECK_SWITCH),
        @LogMessageDoc(level = "ERROR",
                message = "Terminating controller due to storage exception",
                explanation = Controller.ERROR_DATABASE,
                recommendation = LogMessageDoc.CHECK_CONTROLLER),
        @LogMessageDoc(level = "ERROR",
                message = "Could not process message: queue full",
                explanation = "OpenFlow messages are arriving faster than "
                            + "the controller can process them.",
                recommendation = LogMessageDoc.CHECK_CONTROLLER),
        @LogMessageDoc(level = "ERROR",
                message = "Error while processing message "
                        + "from switch {switch} {cause}",
                explanation = "An error occurred processing the switch message",
                recommendation = LogMessageDoc.GENERIC_ACTION)
    })
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {
        if (e.getCause() instanceof ReadTimeoutException) {
            // switch timeout
            log.error("Disconnecting switch {} due to read timeout",
                    getSwitchInfoString());
            counters.switchDisconnectReadTimeout.updateCounterWithFlush();
            ctx.getChannel().close();
        } else if (e.getCause() instanceof HandshakeTimeoutException) {
            log.error("Disconnecting switch {}: failed to complete handshake",
                    getSwitchInfoString());
            counters.switchDisconnectHandshakeTimeout.updateCounterWithFlush();
            ctx.getChannel().close();
        } else if (e.getCause() instanceof ClosedChannelException) {
            log.debug("Channel for sw {} already closed", getSwitchInfoString());
        } else if (e.getCause() instanceof IOException) {
            log.error("Disconnecting switch {} due to IO Error: {}",
                    getSwitchInfoString(), e.getCause().getMessage());
            if (log.isDebugEnabled()) {
                // still print stack trace if debug is enabled
                log.debug("StackTrace for previous Exception: ", e.getCause());
            }
            counters.switchDisconnectIOError.updateCounterWithFlush();
            ctx.getChannel().close();
        } else if (e.getCause() instanceof SwitchStateException) {
            log.error("Disconnecting switch {} due to switch state error: {}",
                    getSwitchInfoString(), e.getCause().getMessage());
            if (log.isDebugEnabled()) {
                // still print stack trace if debug is enabled
                log.debug("StackTrace for previous Exception: ", e.getCause());
            }
            counters.switchDisconnectSwitchStateException.updateCounterWithFlush();
            ctx.getChannel().close();
        } else if (e.getCause() instanceof OFParseError) {
            log.error("Disconnecting switch "
                    + getSwitchInfoString() +
                    " due to message parse failure",
                    e.getCause());
            counters.switchDisconnectParseError.updateCounterWithFlush();
            ctx.getChannel().close();
        } else if (e.getCause() instanceof RejectedExecutionException) {
            log.warn("Could not process message: queue full");
            counters.rejectedExecutionException.updateCounterWithFlush();
        } else {
            log.error("Error while processing message from switch "
                    + getSwitchInfoString()
                    + "state " + this.state, e.getCause());
            counters.switchDisconnectOtherException.updateCounterWithFlush();
            ctx.getChannel().close();
        }
    }

    @Override
    public String toString() {
        return getSwitchInfoString();
    }

    @Override
    public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e)
            throws Exception {
        OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
        OFMessage m = factory.buildEchoRequest().build();
        log.info("Sending Echo Request on idle channel: {}",
                e.getChannel().getPipeline().getLast().toString());
        e.getChannel().write(Collections.singletonList(m));
        // XXX S some problems here -- echo request has no transaction id, and
        // echo reply is not correlated to the echo request.
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
            throws Exception {
        if (e.getMessage() instanceof List) {
            @SuppressWarnings("unchecked")
            List<OFMessage> msglist = (List<OFMessage>) e.getMessage();


            for (OFMessage ofm : msglist) {
                counters.messageReceived.updateCounterNoFlush();
                // Do the actual packet processing
                state.processOFMessage(this, ofm);
            }
        } else {
            counters.messageReceived.updateCounterNoFlush();
            state.processOFMessage(this, (OFMessage) e.getMessage());
        }
    }



    //*************************
    //  Channel utility methods
    //*************************

    /**
     * Is this a state in which the handshake has completed?
     * @return true if the handshake is complete
     */
    public boolean isHandshakeComplete() {
        return this.state.isHandshakeComplete();
    }

    private void dispatchMessage(OFMessage m) throws IOException {
        sw.handleMessage(m);
    }

    /**
     * Return a string describing this switch based on the already available
     * information (DPID and/or remote socket).
     * @return
     */
    private String getSwitchInfoString() {
        if (sw != null) {
            return sw.toString();
        }
        String channelString;
        if (channel == null || channel.getRemoteAddress() == null) {
            channelString = "?";
        } else {
            channelString = channel.getRemoteAddress().toString();
        }
        String dpidString;
        if (featuresReply == null) {
            dpidString = "?";
        } else {
            dpidString = featuresReply.getDatapathId().toString();
        }
        return String.format("[%s DPID[%s]]", channelString, dpidString);
    }

    /**
     * Update the channels state. Only called from the state machine.
     * TODO: enforce restricted state transitions
     * @param state
     */
    private void setState(ChannelState state) {
        this.state = state;
    }

    /**
     * Send hello message to the switch using the handshake transactions ids.
     * @throws IOException
     */
    private void sendHandshakeHelloMessage() throws IOException {
        // The OF protocol requires us to start things off by sending the highest
        // version of the protocol supported.

        // bitmap represents OF1.0 (ofp_version=0x01) and OF1.3 (ofp_version=0x04)
        // see Sec. 7.5.1 of the OF1.3.4 spec
        U32 bitmap = U32.ofRaw(0x00000012);
        OFHelloElem hem = factory13.buildHelloElemVersionbitmap()
                .setBitmaps(Collections.singletonList(bitmap))
                .build();
        OFMessage.Builder mb = factory13.buildHello()
                .setXid(this.handshakeTransactionIds--)
                .setElements(Collections.singletonList(hem));
        log.info("Sending OF_13 Hello to {}", channel.getRemoteAddress());
        channel.write(Collections.singletonList(mb.build()));
    }

    /**
     * Send featuresRequest msg to the switch using the handshake transactions ids.
     * @throws IOException
     */
    private void sendHandshakeFeaturesRequestMessage() throws IOException {
        OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
        OFMessage m = factory.buildFeaturesRequest()
                .setXid(this.handshakeTransactionIds--)
                .build();
        channel.write(Collections.singletonList(m));
    }

    private void setSwitchRole(Role role) {
        sw.setRole(role);
    }

    /**
     * Send the configuration requests to tell the switch we want full
     * packets.
     * @throws IOException
     */
    private void sendHandshakeSetConfig() throws IOException {
        OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
        //log.debug("Sending CONFIG_REQUEST to {}", channel.getRemoteAddress());
        List<OFMessage> msglist = new ArrayList<OFMessage>(3);

        // Ensure we receive the full packet via PacketIn
        // FIXME: We don't set the reassembly flags.
        OFSetConfig sc = factory
                .buildSetConfig()
                .setMissSendLen((short) 0xffff)
                .setXid(this.handshakeTransactionIds--)
                .build();
        msglist.add(sc);

        // Barrier
        OFBarrierRequest br = factory
                .buildBarrierRequest()
                .setXid(this.handshakeTransactionIds--)
                .build();
        msglist.add(br);

        // Verify (need barrier?)
        OFGetConfigRequest gcr = factory
                .buildGetConfigRequest()
                .setXid(this.handshakeTransactionIds--)
                .build();
        msglist.add(gcr);
        channel.write(msglist);
    }

    /**
     * send a description state request.
     * @throws IOException
     */
    private void sendHandshakeDescriptionStatsRequest() throws IOException {
        // Get Description to set switch-specific flags
        OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
        OFDescStatsRequest dreq = factory
                .buildDescStatsRequest()
                .setXid(handshakeTransactionIds--)
                .build();
        channel.write(Collections.singletonList(dreq));
    }

    private void sendHandshakeOFPortDescRequest() throws IOException {
        // Get port description for 1.3 switch
        OFPortDescStatsRequest preq = factory13
                .buildPortDescStatsRequest()
                .setXid(handshakeTransactionIds--)
                .build();
        channel.write(Collections.singletonList(preq));
    }

    ChannelState getStateForTesting() {
        return state;
    }

    void useRoleChangerWithOtherTimeoutForTesting(long roleTimeoutMs) {
        roleChanger = new RoleChanger(roleTimeoutMs);
    }


}
