示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
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)