diff options
author | elie <elie> | 2013-09-07 14:20:04 +0000 |
---|---|---|
committer | elie <elie> | 2013-09-07 14:20:04 +0000 |
commit | 690ea8ee6ae1ff16b184c8c17a6acda681613b6d (patch) | |
tree | aa01889e30f7410beab85156e1fa465e0f00bf24 /pysnmp/carrier | |
parent | 7c88869118305527be9a6aa52ce8f40e9216ee3b (diff) | |
download | pysnmp-git-690ea8ee6ae1ff16b184c8c17a6acda681613b6d.tar.gz |
* A single instance of transport dispatcher can now serve multiple
receivers (identified by IDs) chosen by a public data routing method.
* SnmpEngine.[un]registerTransportDispatcher() methods now accept optional
receiver ID token to be used by transport dispatcher's data router. This
allows for multiple SNMP engines registration with a single transport
dispatcher.
* Relevant example added
Diffstat (limited to 'pysnmp/carrier')
-rw-r--r-- | pysnmp/carrier/base.py | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/pysnmp/carrier/base.py b/pysnmp/carrier/base.py index ccd3d512..13ada404 100644 --- a/pysnmp/carrier/base.py +++ b/pysnmp/carrier/base.py @@ -22,44 +22,64 @@ class TimerCallable: class AbstractTransportDispatcher: def __init__(self): self.__transports = {} + self.__transportDomainMap = {} self.__jobs = {} - self.__recvCbFun = None + self.__recvCallables = {} self.__timerCallables = [] self.__ticks = 0 self.__timerResolution = 0.5 self.__timerDelta = self.__timerResolution * 0.05 self.__nextTime = 0 + # default data routing callback function. + self.__routingCbFun = lambda x,y,z: x def _cbFun(self, incomingTransport, transportAddress, incomingMessage): - for name, transport in self.__transports.items(): - if transport is incomingTransport: - transportDomain = name - break + if incomingTransport in self.__transportDomainMap: + transportDomain = self.__transportDomainMap[incomingTransport] else: raise error.CarrierError( 'Unregistered transport %s' % (incomingTransport,) ) - - if self.__recvCbFun: - self.__recvCbFun( + + recvId = self.__routingCbFun( + transportDomain, transportAddress, incomingMessage + ) + + if recvId in self.__recvCallables: + self.__recvCallables[recvId]( self, transportDomain, transportAddress, incomingMessage - ) + ) else: raise error.CarrierError( - 'Receive callback not registered -- loosing incoming event' - ) + 'No callback for "%r" found - loosing incoming event'%(recvId,) + ) # Dispatcher API - def registerRecvCbFun(self, recvCbFun): - if self.__recvCbFun: - raise error.CarrierError( - 'Receive callback already registered' - ) - self.__recvCbFun = recvCbFun + def registerRoutingCbFun(self, routingCbFun): + if self.__routingCbFun: + raise error.CarrierError( + 'Data routing callback already registered' + ) + self.__routingCbFun = routingCbFun + + def unregisterRoutingCbFun(self): + if self.__routingCbFun: + self.__routingCbFun = None - def unregisterRecvCbFun(self): - self.__recvCbFun = None + def registerRecvCbFun(self, recvCb, recvId=None): + if recvId in self.__recvCallables: + raise error.CarrierError( + 'Receive callback %r already registered' % (recvId is None and '<default>' or recvId,) + ) + self.__recvCallables[recvId] = recvCb + + def unregisterRecvCbFun(self, recvId=None): + if recvId is None: + self.__recvCallables = [] + else: + if recvId in self.__recvCallables: + del self.__recvCallables[recvId] def registerTimerCbFun(self, timerCbFun, tickInterval=None): if not tickInterval: @@ -79,6 +99,7 @@ class AbstractTransportDispatcher: ) transport.registerCbFun(self._cbFun) self.__transports[tDomain] = transport + self.__transportDomainMap[transport] = tDomain def unregisterTransport(self, tDomain): if tDomain not in self.__transports: @@ -86,6 +107,7 @@ class AbstractTransportDispatcher: 'Transport %s not registered' % (tDomain,) ) self.__transports[tDomain].unregisterCbFun() + del self.__transportDomainMap[self.__transports[tDomain]] del self.__transports[tDomain] def getTransport(self, transportDomain): |