<s> """<STR_LIT>""" <EOL> import collections <EOL> import logging <EOL> import random <EOL> import struct <EOL> import threading <EOL> from twisted . internet import error <EOL> import twisted . internet . reactor <EOL> from openfaucet import oferror <EOL> from openfaucet import ofproto <EOL> class Callable ( collections . namedtuple ( '<STR_LIT>' , ( <EOL> '<STR_LIT>' , '<STR_LIT:args>' , '<STR_LIT>' ) ) ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def make_callable ( cls , callable , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> return Callable ( callable , args , kwargs ) <EOL> def __call__ ( self , * first_args , ** first_kwargs ) : <EOL> """<STR_LIT>""" <EOL> if not self . args : <EOL> args = first_args <EOL> elif not first_args : <EOL> args = self . args <EOL> else : <EOL> args = first_args + self . args <EOL> if not self . kwargs : <EOL> kwargs = first_kwargs <EOL> elif not first_kwargs : <EOL> kwargs = self . kwargs <EOL> else : <EOL> kwargs = self . kwargs . copy ( ) <EOL> kwargs . update ( first_kwargs ) <EOL> self . callable ( * args , ** kwargs ) <EOL> PendingOperation = collections . namedtuple ( '<STR_LIT>' , ( <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> class OpenflowProtocolOperations ( ofproto . OpenflowProtocol ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> """<STR_LIT>""" <EOL> ofproto . OpenflowProtocol . __init__ ( self ) <EOL> self . _pending_ops_lock = threading . Lock ( ) <EOL> self . reactor = twisted . internet . reactor <EOL> self . default_op_timeout = <NUM_LIT> <EOL> self . echo_op_period = <NUM_LIT> <EOL> def connectionMade ( self ) : <EOL> """<STR_LIT>""" <EOL> ofproto . OpenflowProtocol . connectionMade ( self ) <EOL> self . logger . info ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , self . reactor , <EOL> self . default_op_timeout , self . echo_op_period , extra = self . log_extra ) <EOL> self . _next_xid = <NUM_LIT:0> <EOL> self . _pending_ops = { } <EOL> self . send_hello ( ) <EOL> self . _echo ( ) <EOL> def connectionLost ( self , reason ) : <EOL> """<STR_LIT>""" <EOL> ofproto . OpenflowProtocol . connectionLost ( self , reason ) <EOL> with self . _pending_ops_lock : <EOL> for pending_op in self . _pending_ops . itervalues ( ) : <EOL> _ , _ , _ , timeout_delayed_call = pending_op <EOL> timeout_delayed_call . cancel ( ) <EOL> self . _pending_ops . clear ( ) <EOL> def _get_next_xid ( self ) : <EOL> """<STR_LIT>""" <EOL> xid = self . _next_xid <EOL> self . _next_xid = ( self . _next_xid + <NUM_LIT:1> ) & <NUM_LIT> <EOL> return xid <EOL> def initiate_operation ( self , success_callback , timeout_callback , <EOL> timeout = None , cookie = None ) : <EOL> """<STR_LIT>""" <EOL> xid = None <EOL> with self . _pending_ops_lock : <EOL> first_xid = xid = self . _get_next_xid ( ) <EOL> while xid in self . _pending_ops : <EOL> xid = self . _get_next_xid ( ) <EOL> if first_xid == xid : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if timeout is None : <EOL> timeout = self . default_op_timeout <EOL> timeout_delayed_call = self . reactor . callLater ( <EOL> timeout , self . _timeout_operation , xid ) <EOL> self . _pending_ops [ xid ] = PendingOperation ( <EOL> cookie , success_callback , timeout_callback , <EOL> timeout_delayed_call ) <EOL> return xid <EOL> def terminate_operation ( self , xid , reply_more = False , cookie = None ) : <EOL> """<STR_LIT>""" <EOL> with self . _pending_ops_lock : <EOL> pending_op = self . _pending_ops . get ( xid , None ) <EOL> if pending_op is not None : <EOL> if pending_op . cookie != cookie : <EOL> self . logger . error ( <EOL> '<STR_LIT>' , <EOL> xid , pending_op . cookie , cookie , extra = self . log_extra ) <EOL> self . raise_error_with_request ( oferror . OFPET_BAD_REQUEST , <EOL> oferror . OFPBRC_BAD_TYPE ) <EOL> if not reply_more : <EOL> del self . _pending_ops [ xid ] <EOL> try : <EOL> pending_op . timeout_delayed_call . cancel ( ) <EOL> except error . AlreadyCalled : <EOL> return None <EOL> return pending_op . success_callback <EOL> def _timeout_operation ( self , xid ) : <EOL> """<STR_LIT>""" <EOL> pending_op = None <EOL> with self . _pending_ops_lock : <EOL> pending_op = self . _pending_ops . pop ( xid , None ) <EOL> if pending_op is not None : <EOL> self . logger . info ( '<STR_LIT>' , xid , <EOL> extra = self . log_extra ) <EOL> if pending_op . timeout_callback is not None : <EOL> pending_op . timeout_callback ( ) <EOL> def handle_echo_request ( self , xid , data ) : <EOL> """<STR_LIT>""" <EOL> self . send_echo_reply ( xid , ( data , ) ) <EOL> def handle_echo_reply ( self , xid , data ) : <EOL> """<STR_LIT>""" <EOL> success_callable = self . terminate_operation ( <EOL> xid , cookie = ofproto . OFPT_ECHO_REQUEST ) <EOL> if success_callable is not None : <EOL> success_callable ( data ) <EOL> def _echo ( self ) : <EOL> """<STR_LIT>""" <EOL> sent_data = struct . pack ( '<STR_LIT>' , random . getrandbits ( <NUM_LIT:32> ) ) <EOL> xid = self . initiate_operation ( <EOL> Callable . make_callable ( self . _handle_echo_termination , sent_data ) , <EOL> self . _handle_echo_timeout , <EOL> timeout = None , cookie = ofproto . OFPT_ECHO_REQUEST ) <EOL> self . send_echo_request ( xid , sent_data ) <EOL> def _handle_echo_termination ( self , data , sent_data ) : <EOL> """<STR_LIT>""" <EOL> if data != sent_data : <EOL> self . logger . error ( '<STR_LIT>' , <EOL> extra = self . log_extra ) <EOL> self . transport . loseConnection ( ) <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> self . reactor . callLater ( self . echo_op_period , self . _echo ) <EOL> def _handle_echo_timeout ( self ) : <EOL> """<STR_LIT>""" <EOL> self . logger . error ( '<STR_LIT>' , extra = self . log_extra ) <EOL> self . transport . loseConnection ( ) <EOL> class OpenflowProtocolOperationsFactory ( ofproto . OpenflowProtocolFactory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , protocol = OpenflowProtocolOperations , <EOL> error_data_bytes = <NUM_LIT:64> , logger = logging . getLogger ( '<STR_LIT>' ) , <EOL> vendor_handlers = ( ) , reactor = twisted . internet . reactor , <EOL> default_op_timeout = <NUM_LIT> , echo_op_period = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> ofproto . OpenflowProtocolFactory . __init__ ( <EOL> self , protocol = protocol , error_data_bytes = error_data_bytes , <EOL> logger = logger , vendor_handlers = vendor_handlers ) <EOL> self . _reactor = reactor <EOL> self . _default_op_timeout = default_op_timeout <EOL> self . _echo_op_period = echo_op_period <EOL> self . _logger . info ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , self . _reactor , <EOL> self . _default_op_timeout , self . _echo_op_period ) <EOL> def buildProtocol ( self , addr ) : <EOL> """<STR_LIT>""" <EOL> p = ofproto . OpenflowProtocolFactory . buildProtocol ( self , addr ) <EOL> p . reactor = self . _reactor <EOL> p . default_op_timeout = self . _default_op_timeout <EOL> p . echo_op_period = self . _echo_op_period <EOL> return p </s>
