<s> """<STR_LIT>""" <EOL> import asyncore <EOL> import socket <EOL> import pickle <EOL> import queue <EOL> from time import time as _time <EOL> from . debugging import ModuleLogger , bacpypes_debugging <EOL> from . core import deferred <EOL> from . task import FunctionTask <EOL> from . comm import PDU , Server <EOL> from . comm import ServiceAccessPoint <EOL> _debug = <NUM_LIT:0> <EOL> _log = ModuleLogger ( globals ( ) ) <EOL> @ bacpypes_debugging <EOL> class UDPActor : <EOL> def __init__ ( self , director , peer ) : <EOL> if _debug : UDPActor . _debug ( "<STR_LIT>" , director , peer ) <EOL> self . director = director <EOL> self . peer = peer <EOL> self . timeout = director . timeout <EOL> if self . timeout > <NUM_LIT:0> : <EOL> self . timer = FunctionTask ( self . IdleTimeout ) <EOL> self . timer . install_task ( _time ( ) + self . timeout ) <EOL> else : <EOL> self . timer = None <EOL> self . director . AddActor ( self ) <EOL> def IdleTimeout ( self ) : <EOL> if _debug : UDPActor . _debug ( "<STR_LIT>" ) <EOL> self . director . RemoveActor ( self ) <EOL> def indication ( self , pdu ) : <EOL> if _debug : UDPActor . _debug ( "<STR_LIT>" , pdu ) <EOL> if self . timer : <EOL> self . timer . install_task ( _time ( ) + self . timeout ) <EOL> self . director . request . put ( pdu ) <EOL> def response ( self , pdu ) : <EOL> if _debug : UDPActor . _debug ( "<STR_LIT>" , pdu ) <EOL> if self . timer : <EOL> self . timer . install_task ( _time ( ) + self . timeout ) <EOL> self . director . response ( pdu ) <EOL> @ bacpypes_debugging <EOL> class UDPPickleActor ( UDPActor ) : <EOL> def __init__ ( self , * args ) : <EOL> if _debug : UDPPickleActor . _debug ( "<STR_LIT>" , args ) <EOL> UDPActor . __init__ ( self , * args ) <EOL> def indication ( self , pdu ) : <EOL> if _debug : UDPPickleActor . _debug ( "<STR_LIT>" , pdu ) <EOL> pdu . pduData = pickle . dumps ( pdu . pduData ) <EOL> UDPActor . indication ( self , pdu ) <EOL> def response ( self , pdu ) : <EOL> if _debug : UDPPickleActor . _debug ( "<STR_LIT>" , pdu ) <EOL> try : <EOL> pdu . pduData = pickle . loads ( pdu . pduData ) <EOL> except : <EOL> UDPPickleActor . _exception ( "<STR_LIT>" ) <EOL> return <EOL> UDPActor . response ( self , pdu ) <EOL> @ bacpypes_debugging <EOL> class UDPDirector ( asyncore . dispatcher , Server , ServiceAccessPoint ) : <EOL> def __init__ ( self , address , timeout = <NUM_LIT:0> , reuse = False , actorClass = UDPActor , sid = None , sapID = None ) : <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , address , timeout , reuse , actorClass , sid , sapID ) <EOL> Server . __init__ ( self , sid ) <EOL> ServiceAccessPoint . __init__ ( self , sapID ) <EOL> if not issubclass ( actorClass , UDPActor ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> self . actorClass = actorClass <EOL> self . timeout = timeout <EOL> self . address = address <EOL> asyncore . dispatcher . __init__ ( self ) <EOL> self . create_socket ( socket . AF_INET , socket . SOCK_DGRAM ) <EOL> if reuse : <EOL> self . set_reuse_addr ( ) <EOL> self . bind ( address ) <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , self . socket . getsockname ( ) ) <EOL> self . socket . setsockopt ( socket . SOL_SOCKET , socket . SO_BROADCAST , <NUM_LIT:1> ) <EOL> self . request = queue . Queue ( ) <EOL> self . peers = { } <EOL> def AddActor ( self , actor ) : <EOL> """<STR_LIT>""" <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , actor ) <EOL> self . peers [ actor . peer ] = actor <EOL> if self . serviceElement : <EOL> self . sap_request ( addPeer = actor . peer ) <EOL> def RemoveActor ( self , actor ) : <EOL> """<STR_LIT>""" <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , actor ) <EOL> del self . peers [ actor . peer ] <EOL> if self . serviceElement : <EOL> self . sap_request ( delPeer = actor . peer ) <EOL> def GetActor ( self , address ) : <EOL> return self . peers . get ( address , None ) <EOL> def handle_connect ( self ) : <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" ) <EOL> def readable ( self ) : <EOL> return <NUM_LIT:1> <EOL> def handle_read ( self ) : <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" ) <EOL> try : <EOL> msg , addr = self . socket . recvfrom ( <NUM_LIT> ) <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" , len ( msg ) , addr ) <EOL> deferred ( self . _response , PDU ( msg , source = addr ) ) <EOL> except socket . timeout as err : <EOL> deferred ( UDPDirector . _error , "<STR_LIT>" , err ) <EOL> except OSError as err : <EOL> if err . args [ <NUM_LIT:0> ] == <NUM_LIT:11> : <EOL> pass <EOL> else : <EOL> deferred ( UDPDirector . _error , "<STR_LIT>" , err ) <EOL> def writable ( self ) : <EOL> """<STR_LIT>""" <EOL> return ( not self . request . empty ( ) ) <EOL> def handle_write ( self ) : <EOL> """<STR_LIT>""" <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" ) <EOL> try : <EOL> pdu = self . request . get ( ) <EOL> sent = self . socket . sendto ( pdu . pduData , pdu . pduDestination ) <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" , sent , pdu . pduDestination ) <EOL> except OSError as err : <EOL> deferred ( UDPDirector . _error , "<STR_LIT>" , err ) <EOL> def handle_close ( self ) : <EOL> """<STR_LIT>""" <EOL> if _debug : deferred ( UDPDirector . _debug , "<STR_LIT>" ) <EOL> self . close ( ) <EOL> self . socket = None <EOL> def indication ( self , pdu ) : <EOL> """<STR_LIT>""" <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , pdu ) <EOL> addr = pdu . pduDestination <EOL> peer = self . peers . get ( addr , None ) <EOL> if not peer : <EOL> peer = self . actorClass ( self , addr ) <EOL> peer . indication ( pdu ) <EOL> def _response ( self , pdu ) : <EOL> """<STR_LIT>""" <EOL> if _debug : UDPDirector . _debug ( "<STR_LIT>" , pdu ) <EOL> addr = pdu . pduSource <EOL> peer = self . peers . get ( addr , None ) <EOL> if not peer : <EOL> peer = self . actorClass ( self , addr ) <EOL> peer . response ( pdu ) </s>
