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:
parent
f5212f8bf4
commit
92a376a68a
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user