def do_WritePropertyRequest(self, apdu): """Change the value of some property of one of our objects.""" if _debug: Application._debug("do_WritePropertyRequest %r", apdu) # get the object obj = self.get_object_id(apdu.objectIdentifier) if _debug: Application._debug(" - object: %r", obj) if not obj: resp = Error(errorClass='object', errorCode='unknownObject', context=apdu) else: try: # check if the property exists if obj.ReadProperty(apdu.propertyIdentifier, apdu.propertyArrayIndex) is None: raise PropertyError, apdu.propertyIdentifier # get the datatype, special case for null if apdu.propertyValue.is_application_class_null(): datatype = Null else: datatype = obj.get_datatype(apdu.propertyIdentifier) if _debug: Application._debug(" - datatype: %r", datatype) # special case for array parts, others are managed by cast_out if issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: value = apdu.propertyValue.cast_out(Unsigned) else: value = apdu.propertyValue.cast_out(datatype.subtype) else: value = apdu.propertyValue.cast_out(datatype) if _debug: Application._debug(" - value: %r", value) # change the value value = obj.WriteProperty(apdu.propertyIdentifier, value, apdu.propertyArrayIndex, apdu.priority) # success resp = SimpleAckPDU(context=apdu) except PropertyError: resp = Error(errorClass='object', errorCode='unknownProperty', context=apdu) if _debug: Application._debug(" - resp: %r", resp) # return the result self.response(resp)
def indication(self, apdu): if _debug: Application._debug("indication %r", apdu) # get a helper function helperName = "do_" + apdu.__class__.__name__ helperFn = getattr(self, helperName, None) if _debug: Application._debug(" - helperFn: %r", helperFn) # send back a reject for unrecognized services if not helperFn: if isinstance(apdu, ConfirmedRequestPDU): response = RejectPDU(apdu.apduInvokeID, RejectReason.UNRECOGNIZEDSERVICE, context=apdu) self.response(response) return # pass the apdu on to the helper function try: helperFn(apdu) except ExecutionError, err: if _debug: Application._debug(" - execution error: %r", err) # send back an error if isinstance(apdu, ConfirmedRequestPDU): resp = Error(errorClass=err.errorClass, errorCode=err.errorCode, context=apdu) self.response(resp)
def do_ReadPropertyRequest(self, apdu): """Return the value of some property of one of our objects.""" if _debug: MultiDeviceApplication._debug("do_ReadPropertyRequest %r", apdu) print "doing read property request" # extract the object identifier objId = apdu.objectIdentifier print objId print apdu.propertyIdentifier # check for wildcard if (objId == ('device', 4194303)): if _debug: MultiDeviceApplication._debug(" - wildcard device identifier") objId = self.localDevice.objectIdentifier for dev_id in self.localDevices: dev = localDevices[dev_id] apdu.objectIdentifier = dev.objectIdentifier do_ReadPropertyRequest(self,apdu) return # get the object obj = self.get_object_id(objId[1]) if obj == None: print "objnone" if _debug: MultiDeviceApplication._debug(" - object: %r", obj) if not obj: resp = Error(errorClass='object', errorCode='unknownObject', context=apdu) else: try: # get the datatype datatype = obj.get_datatype(apdu.propertyIdentifier) if _debug: MultiDeviceApplication._debug(" - datatype: %r", datatype) # get the value value = obj.ReadProperty(apdu.propertyIdentifier, apdu.propertyArrayIndex) print value if _debug: MultiDeviceApplication._debug(" - value: %r", value) if value is None: raise PropertyError, apdu.propertyIdentifier # change atomic values into something encodeable if issubclass(datatype, Atomic): value = datatype(value) elif issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: value = Unsigned(value) elif issubclass(datatype.subtype, Atomic): value = datatype.subtype(value) elif not isinstance(value, datatype.subtype): raise TypeError, "invalid result datatype, expecting %s and got %s" \ % (datatype.subtype.__name__, type(value).__name__) elif not isinstance(value, datatype): raise TypeError, "invalid result datatype, expecting %s and got %s" \ % (datatype.__name__, type(value).__name__) if _debug: MultiDeviceApplication._debug(" - encodeable value: %r", value) # this is a ReadProperty ack resp = ReadPropertyACK(context=apdu) resp.objectIdentifier = objId resp.propertyIdentifier = apdu.propertyIdentifier resp.propertyArrayIndex = apdu.propertyArrayIndex # save the result in the property value resp.propertyValue = Any() resp.propertyValue.cast_in(value) except PropertyError: resp = Error(errorClass='object', errorCode='unknownProperty', context=apdu) if _debug: MultiDeviceApplication._debug(" - resp: %r", resp) # return the result self.response(resp)
def do_AtomicWriteFileRequest(self, apdu): """Return one of our records.""" if _debug: Application._debug("do_AtomicWriteFileRequest %r", apdu) if (apdu.fileIdentifier[0] != 'file'): resp = Error(errorClass='services', errorCode='inconsistentObjectType', context=apdu) if _debug: Application._debug(" - error resp: %r", resp) self.response(resp) return # get the object obj = self.get_object_id(apdu.fileIdentifier) if _debug: Application._debug(" - object: %r", obj) if not obj: resp = Error(errorClass='object', errorCode='unknownObject', context=apdu) elif apdu.accessMethod.recordAccess: # check against the object if obj.fileAccessMethod != 'recordAccess': resp = Error(errorClass='services', errorCode='invalidFileAccessMethod', context=apdu) if _debug: Application._debug(" - error resp: %r", resp) self.response(resp) return # pass along to the object start_record = obj.WriteFile( apdu.accessMethod.recordAccess.fileStartRecord, apdu.accessMethod.recordAccess.recordCount, apdu.accessMethod.recordAccess.fileRecordData, ) if _debug: Application._debug(" - start_record: %r", start_record) # this is an ack resp = AtomicWriteFileACK( context=apdu, fileStartRecord=start_record, ) elif apdu.accessMethod.streamAccess: # check against the object if obj.fileAccessMethod != 'streamAccess': resp = Error(errorClass='services', errorCode='invalidFileAccessMethod', context=apdu) if _debug: Application._debug(" - error resp: %r", resp) self.response(resp) return # pass along to the object start_position = obj.WriteFile( apdu.accessMethod.streamAccess.fileStartPosition, apdu.accessMethod.streamAccess.fileData, ) if _debug: Application._debug(" - start_position: %r", start_position) # this is an ack resp = AtomicWriteFileACK( context=apdu, fileStartPosition=start_position, ) if _debug: Application._debug(" - resp: %r", resp) # return the result self.response(resp)
def do_AtomicReadFileRequest(self, apdu): """Return one of our records.""" if _debug: Application._debug("do_AtomicReadFileRequest %r", apdu) if (apdu.fileIdentifier[0] != 'file'): resp = Error(errorClass='services', errorCode='inconsistentObjectType', context=apdu) if _debug: Application._debug(" - error resp: %r", resp) self.response(resp) return # get the object obj = self.get_object_id(apdu.fileIdentifier) if _debug: Application._debug(" - object: %r", obj) if not obj: resp = Error(errorClass='object', errorCode='unknownObject', context=apdu) elif apdu.accessMethod.recordAccess: # check against the object if obj.fileAccessMethod != 'recordAccess': resp = Error(errorClass='services', errorCode='invalidFileAccessMethod', context=apdu) ### verify start is valid - double check this (empty files?) elif (apdu.accessMethod.recordAccess.fileStartRecord < 0) or \ (apdu.accessMethod.recordAccess.fileStartRecord >= len(obj)): resp = Error(errorClass='services', errorCode='invalidFileStartPosition', context=apdu) else: # pass along to the object end_of_file, record_data = obj.ReadFile( apdu.accessMethod.recordAccess.fileStartRecord, apdu.accessMethod.recordAccess.requestedRecordCount, ) if _debug: Application._debug(" - record_data: %r", record_data) # this is an ack resp = AtomicReadFileACK( context=apdu, endOfFile=end_of_file, accessMethod=AtomicReadFileACKAccessMethodChoice( recordAccess=AtomicReadFileACKAccessMethodRecordAccess( fileStartRecord=apdu.accessMethod.recordAccess. fileStartRecord, returnedRecordCount=len(record_data), fileRecordData=record_data, ), ), ) elif apdu.accessMethod.streamAccess: # check against the object if obj.fileAccessMethod != 'streamAccess': resp = Error(errorClass='services', errorCode='invalidFileAccessMethod', context=apdu) ### verify start is valid - double check this (empty files?) elif (apdu.accessMethod.streamAccess.fileStartPosition < 0) or \ (apdu.accessMethod.streamAccess.fileStartPosition >= len(obj)): resp = Error(errorClass='services', errorCode='invalidFileStartPosition', context=apdu) else: # pass along to the object end_of_file, record_data = obj.ReadFile( apdu.accessMethod.streamAccess.fileStartPosition, apdu.accessMethod.streamAccess.requestedOctetCount, ) if _debug: Application._debug(" - record_data: %r", record_data) # this is an ack resp = AtomicReadFileACK( context=apdu, endOfFile=end_of_file, accessMethod=AtomicReadFileACKAccessMethodChoice( streamAccess=AtomicReadFileACKAccessMethodStreamAccess( fileStartPosition=apdu.accessMethod.streamAccess. fileStartPosition, fileData=record_data, ), ), ) if _debug: Application._debug(" - resp: %r", resp) # return the result self.response(resp)
def do_ReadPropertyRequest(self, apdu): """Return the value of some property of one of our objects.""" if _debug: Application._debug("do_ReadPropertyRequest %r", apdu) # extract the object identifier objId = apdu.objectIdentifier # check for wildcard if (objId == ('device', 4194303)): if _debug: Application._debug(" - wildcard device identifier") objId = self.localDevice.objectIdentifier # get the object obj = self.get_object_id(objId) if _debug: Application._debug(" - object: %r", obj) if not obj: resp = Error(errorClass='object', errorCode='unknownObject', context=apdu) else: try: # get the datatype datatype = obj.get_datatype(apdu.propertyIdentifier) if _debug: Application._debug(" - datatype: %r", datatype) # get the value value = obj.ReadProperty(apdu.propertyIdentifier, apdu.propertyArrayIndex) if _debug: Application._debug(" - value: %r", value) if value is None: raise PropertyError, apdu.propertyIdentifier # change atomic values into something encodeable if issubclass(datatype, Atomic): value = datatype(value) elif issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: value = Unsigned(value) elif issubclass(datatype.subtype, Atomic): value = datatype.subtype(value) elif not isinstance(value, datatype.subtype): raise TypeError, "invalid result datatype, expecting %s and got %s" \ % (datatype.subtype.__name__, type(value).__name__) elif not isinstance(value, datatype): raise TypeError, "invalid result datatype, expecting %s and got %s" \ % (datatype.__name__, type(value).__name__) if _debug: Application._debug(" - encodeable value: %r", value) # this is a ReadProperty ack resp = ReadPropertyACK(context=apdu) resp.objectIdentifier = objId resp.propertyIdentifier = apdu.propertyIdentifier resp.propertyArrayIndex = apdu.propertyArrayIndex # save the result in the property value resp.propertyValue = Any() resp.propertyValue.cast_in(value) except PropertyError: resp = Error(errorClass='object', errorCode='unknownProperty', context=apdu) if _debug: Application._debug(" - resp: %r", resp) # return the result self.response(resp)
class Application(ApplicationServiceElement, Logging): def __init__(self, localDevice, localAddress, aseID=None): if _debug: Application._debug("__init__ %r %r aseID=%r", localDevice, localAddress, aseID) ApplicationServiceElement.__init__(self, aseID) # keep track of the local device self.localDevice = localDevice # allow the address to be cast to the correct type if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) # local objects by ID and name self.objectName = {localDevice.objectName: localDevice} self.objectIdentifier = {localDevice.objectIdentifier: localDevice} def add_object(self, obj): """Add an object to the local collection.""" if _debug: Application._debug("add_object %r", obj) # extract the object name and identifier object_name = obj.objectName if not object_name: raise RuntimeError, "object name required" object_identifier = obj.objectIdentifier if not object_identifier: raise RuntimeError, "object identifier required" # make sure it hasn't already been defined if object_name in self.objectName: raise RuntimeError, "already an object with name '%s'" % ( object_name, ) if object_identifier in self.objectIdentifier: raise RuntimeError, "already an object with identifier %s" % ( object_identifier, ) # now put it in local dictionaries self.objectName[object_name] = obj self.objectIdentifier[object_identifier] = obj # append the new object's identifier to the device's object list self.localDevice.objectList.append(object_identifier) def delete_object(self, obj): """Add an object to the local collection.""" if _debug: Application._debug("delete_object %r", obj) # extract the object name and identifier object_name = obj.objectName object_identifier = obj.objectIdentifier # delete it from the application del self.objectName[object_name] del self.objectIdentifier[object_identifier] # remove the object's identifier from the device's object list indx = self.localDevice.objectList.index(object_identifier) del self.localDevice.objectList[indx] def get_object_id(self, objid): """Return a local object or None.""" return self.objectIdentifier.get(objid, None) def get_object_name(self, objname): """Return a local object or None.""" return self.objectName.get(objname, None) def iter_objects(self): """Iterate over the objects.""" return self.objectIdentifier.itervalues() #----- def indication(self, apdu): if _debug: Application._debug("indication %r", apdu) # get a helper function helperName = "do_" + apdu.__class__.__name__ helperFn = getattr(self, helperName, None) if _debug: Application._debug(" - helperFn: %r", helperFn) # send back a reject for unrecognized services if not helperFn: if isinstance(apdu, ConfirmedRequestPDU): response = RejectPDU(apdu.apduInvokeID, RejectReason.UNRECOGNIZEDSERVICE, context=apdu) self.response(response) return # pass the apdu on to the helper function try: helperFn(apdu) except ExecutionError, err: if _debug: Application._debug(" - execution error: %r", err) # send back an error if isinstance(apdu, ConfirmedRequestPDU): resp = Error(errorClass=err.errorClass, errorCode=err.errorCode, context=apdu) self.response(resp) except Exception, err: Application._exception("exception: %r", err) # send back an error if isinstance(apdu, ConfirmedRequestPDU): resp = Error(errorClass='device', errorCode='operationalProblem', context=apdu) self.response(resp)