1
0
mirror of https://github.com/JoelBender/bacpypes synced 2025-10-05 22:18:16 +08:00

switch to using IOCBs

This commit is contained in:
Joel Bender 2016-08-30 16:44:29 -04:00
parent f5212f8bf4
commit 92a376a68a

View File

@ -646,34 +646,45 @@ class ChangeOfValueServices(Capability):
# list of active subscriptions # list of active subscriptions
self.active_cov_subscriptions = [] self.active_cov_subscriptions = []
# a queue of confirmed notifications by client address
self.confirmed_notifications_queue = defaultdict(list)
# if there is a local device object, make sure it has an active COV # if there is a local device object, make sure it has an active COV
# subscriptions property # subscriptions property
if self.localDevice and self.localDevice.activeCovSubscriptions is None: if self.localDevice and self.localDevice.activeCovSubscriptions is None:
self.localDevice.add_propert(ActiveCOVSubscriptions) self.localDevice.add_property(ActiveCOVSubscriptions)
def cov_notification(self, cov, request): def cov_notification(self, cov, request):
if _debug: ChangeOfValueServices._debug("cov_notification %s %s", str(cov), str(request)) if _debug: ChangeOfValueServices._debug("cov_notification %s %s", str(cov), str(request))
# if this is confirmed, keep track of the cov # send the request
if cov.confirmed: iocb = self.request(request)
if _debug: ChangeOfValueServices._debug(" - it's confirmed")
notification_list = self.confirmed_notifications_queue[cov.client_addr] # if this is confirmed, add a callback for the response, otherwise it
notification_list.append((request, cov)) # was unconfirmed
if iocb:
iocb.cov = cov
iocb.add_callback(self.cov_confirmation)
# if this isn't the first, wait until the first one is done def cov_confirmation(self, iocb):
if len(notification_list) > 1: if _debug: ChangeOfValueServices._debug("cov_confirmation %r", iocb)
if _debug: ChangeOfValueServices._debug(" - not the first")
return
else:
if _debug: ChangeOfValueServices._debug(" - it's unconfirmed")
# send it along down the stack # do something for success
super(ChangeOfValueServices, self).request(request) if iocb.ioResponse:
if _debug: ChangeOfValueServices._debug(" - apduInvokeID: %r", getattr(request, 'apduInvokeID')) if _debug: ChangeOfValueServices._debug(" - ack")
self.cov_ack(iocb.cov, iocb.args[0], iocb.ioResponse)
elif isinstance(iocb.ioError, Error):
if _debug: ChangeOfValueServices._debug(" - error: %r", iocb.ioError.errorCode)
self.cov_error(iocb.cov, iocb.args[0], iocb.ioError)
elif isinstance(iocb.ioError, RejectPDU):
if _debug: ChangeOfValueServices._debug(" - reject: %r", iocb.ioError.apduAbortRejectReason)
self.cov_reject(iocb.cov, iocb.args[0], iocb.ioError)
elif isinstance(iocb.ioError, AbortPDU):
if _debug: ChangeOfValueServices._debug(" - abort: %r", iocb.ioError.apduAbortRejectReason)
self.cov_abort(iocb.cov, iocb.args[0], iocb.ioError)
def cov_ack(self, cov, request, response):
if _debug: ChangeOfValueServices._debug("cov_ack %r %r %r", cov, request, response)
def cov_error(self, cov, request, response): def cov_error(self, cov, request, response):
if _debug: ChangeOfValueServices._debug("cov_error %r %r %r", cov, request, response) if _debug: ChangeOfValueServices._debug("cov_error %r %r %r", cov, request, response)
@ -684,66 +695,9 @@ class ChangeOfValueServices(Capability):
def cov_abort(self, cov, request, response): def cov_abort(self, cov, request, response):
if _debug: ChangeOfValueServices._debug("cov_abort %r %r %r", cov, request, response) if _debug: ChangeOfValueServices._debug("cov_abort %r %r %r", cov, request, response)
# delete the rest of the pending requests for this client ### delete the rest of the pending requests for this client
del self.confirmed_notifications_queue[cov.client_addr][:]
if _debug: ChangeOfValueServices._debug(" - other notifications deleted") if _debug: ChangeOfValueServices._debug(" - other notifications deleted")
def confirmation(self, apdu):
if _debug: ChangeOfValueServices._debug("confirmation %r", apdu)
if _debug: ChangeOfValueServices._debug(" - queue keys: %r", self.confirmed_notifications_queue.keys())
# if this isn't from someone we care about, toss it
if apdu.pduSource not in self.confirmed_notifications_queue:
if _debug: ChangeOfValueServices._debug(" - not someone we are tracking")
# pass along to the application
super(ChangeOfValueServices, self).confirmation(apdu)
return
# refer to the notification list for this client
notification_list = self.confirmed_notifications_queue[apdu.pduSource]
if _debug: ChangeOfValueServices._debug(" - notification_list: %r", notification_list)
# peek at the front of the list
request, cov = notification_list[0]
if _debug: ChangeOfValueServices._debug(" - request: %s", request)
# line up the invoke id
if apdu.apduInvokeID == request.apduInvokeID:
if _debug: ChangeOfValueServices._debug(" - request/response align")
notification_list.pop(0)
else:
if _debug: ChangeOfValueServices._debug(" - request/response do not align")
# pass along to the application
super(ChangeOfValueServices, self).confirmation(apdu)
return
if isinstance(apdu, Error):
if _debug: ChangeOfValueServices._debug(" - error: %r", apdu.errorCode)
self.cov_error(cov, request, apdu)
elif isinstance(apdu, RejectPDU):
if _debug: ChangeOfValueServices._debug(" - reject: %r", apdu.apduAbortRejectReason)
self.cov_reject(cov, request, apdu)
elif isinstance(apdu, AbortPDU):
if _debug: ChangeOfValueServices._debug(" - abort: %r", apdu.apduAbortRejectReason)
self.cov_abort(cov, request, apdu)
# if the notification list is empty, delete the reference
if not notification_list:
if _debug: ChangeOfValueServices._debug(" - no other pending notifications")
del self.confirmed_notifications_queue[apdu.pduSource]
return
# peek at the front of the list for the next request
request, cov = notification_list[0]
if _debug: ChangeOfValueServices._debug(" - next notification: %r", request)
# send it along down the stack
super(ChangeOfValueServices, self).request(request)
def do_SubscribeCOVRequest(self, apdu): def do_SubscribeCOVRequest(self, apdu):
if _debug: ChangeOfValueServices._debug("do_SubscribeCOVRequest %r", apdu) if _debug: ChangeOfValueServices._debug("do_SubscribeCOVRequest %r", apdu)