├── .github └── workflows │ └── sonarqube.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ └── codeStyleConfig.xml ├── compiler.xml ├── encodings.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── README.md ├── license.txt ├── pom.xml └── src ├── main └── java │ └── com │ └── serotonin │ └── bacnet4j │ ├── LocalDevice.java │ ├── NotificationClassListener.java │ ├── RemoteDevice.java │ ├── RemoteObject.java │ ├── ResponseConsumer.java │ ├── ResponseConsumerAdapter.java │ ├── ServiceFuture.java │ ├── apdu │ ├── APDU.java │ ├── Abort.java │ ├── AckAPDU.java │ ├── ComplexACK.java │ ├── ConfirmedRequest.java │ ├── Error.java │ ├── Reject.java │ ├── SegmentACK.java │ ├── Segmentable.java │ ├── SimpleACK.java │ └── UnconfirmedRequest.java │ ├── cache │ ├── CachePolicies.java │ ├── CachedRemoteEntity.java │ ├── RemoteEntityCache.java │ └── RemoteEntityCachePolicy.java │ ├── enums │ ├── DayOfWeek.java │ ├── MaxApduLength.java │ ├── MaxSegments.java │ └── Month.java │ ├── event │ ├── DefaultDeviceEventListener.java │ ├── DefaultExceptionListener.java │ ├── DefaultReinitializeDeviceHandler.java │ ├── DeviceEventAdapter.java │ ├── DeviceEventHandler.java │ ├── DeviceEventListener.java │ ├── ExceptionDispatcher.java │ ├── ExceptionListener.java │ ├── IAmListener.java │ ├── PrivateTransferHandler.java │ └── ReinitializeDeviceHandler.java │ ├── exception │ ├── AbortAPDUException.java │ ├── BACnetAbortException.java │ ├── BACnetErrorException.java │ ├── BACnetException.java │ ├── BACnetRecoverableException.java │ ├── BACnetRejectException.java │ ├── BACnetRuntimeException.java │ ├── BACnetServiceException.java │ ├── BACnetTimeoutException.java │ ├── CommunicationDisabledException.java │ ├── ConfirmedRequestParseException.java │ ├── ErrorAPDUException.java │ ├── IllegalPduTypeException.java │ ├── NotImplementedException.java │ ├── PropertyValueException.java │ ├── ReflectionException.java │ ├── RejectAPDUException.java │ ├── SegmentedMessageAbortedException.java │ └── ServiceTooBigException.java │ ├── npdu │ ├── MessageValidationException.java │ ├── NPCI.java │ ├── NPDU.java │ ├── Network.java │ ├── NetworkIdentifier.java │ ├── NetworkUtils.java │ ├── ip │ │ ├── InetAddrCache.java │ │ ├── IpNetwork.java │ │ ├── IpNetworkBuilder.java │ │ ├── IpNetworkIdentifier.java │ │ └── IpNetworkUtils.java │ ├── ipv6 │ │ ├── Ipv6Network.java │ │ ├── Ipv6NetworkBuilder.java │ │ ├── Ipv6NetworkIdentifier.java │ │ └── Ipv6NetworkUtils.java │ ├── mstp │ │ ├── Constants.java │ │ ├── DataCRC.java │ │ ├── Frame.java │ │ ├── FrameResponseListener.java │ │ ├── FrameType.java │ │ ├── HeaderCRC.java │ │ ├── MasterNode.java │ │ ├── MstpNetwork.java │ │ ├── MstpNetworkIdentifier.java │ │ ├── MstpNetworkUtils.java │ │ ├── MstpNode.java │ │ ├── RealtimeMasterNode.java │ │ ├── SlaveNode.java │ │ └── realtime │ │ │ ├── RealtimeDriver.java │ │ │ └── RealtimeDriverProperties.java │ └── test │ │ ├── TestNetwork.java │ │ ├── TestNetworkIdentifier.java │ │ ├── TestNetworkMap.java │ │ └── TestNetworkUtils.java │ ├── obj │ ├── AbstractMixin.java │ ├── AccumulatorObject.java │ ├── AlertEnrollmentObject.java │ ├── AnalogInputObject.java │ ├── AnalogOutputObject.java │ ├── AnalogValueObject.java │ ├── AveragingObject.java │ ├── BACnetObject.java │ ├── BACnetObjectListener.java │ ├── BinaryInputObject.java │ ├── BinaryOutputObject.java │ ├── BinaryValueObject.java │ ├── CalendarObject.java │ ├── CharacterStringObject.java │ ├── DeviceObject.java │ ├── EventEnrollmentObject.java │ ├── EventLogObject.java │ ├── FileObject.java │ ├── GroupObject.java │ ├── LifeSafety.java │ ├── LifeSafetyPointObject.java │ ├── LifeSafetyZoneObject.java │ ├── MultistateInputObject.java │ ├── MultistateOutputObject.java │ ├── MultistateValueObject.java │ ├── NotificationClassObject.java │ ├── NotificationForwarderObject.java │ ├── ObjectProperties.java │ ├── ObjectPropertyIdentifier.java │ ├── ObjectPropertyTypeDefinition.java │ ├── PropertyTypeDefinition.java │ ├── PulseConverterObject.java │ ├── ScheduleObject.java │ ├── TrendLogMultipleObject.java │ ├── TrendLogObject.java │ ├── fileAccess │ │ ├── CrlfDelimitedFileAccess.java │ │ ├── FileAccess.java │ │ ├── NullFileAccess.java │ │ ├── RecordAccess.java │ │ └── StreamAccess.java │ ├── logBuffer │ │ ├── ILogRecord.java │ │ ├── LinkedListLogBuffer.java │ │ └── LogBuffer.java │ └── mixin │ │ ├── ActiveCovSubscriptionMixin.java │ │ ├── ActiveTimeMixin.java │ │ ├── CommandableMixin.java │ │ ├── CovContext.java │ │ ├── CovReportingMixin.java │ │ ├── HasStatusFlagsMixin.java │ │ ├── LifeSafetyMixin.java │ │ ├── MultistateMixin.java │ │ ├── ObjectIdAndNameMixin.java │ │ ├── ObjectListMixin.java │ │ ├── PollingDelegate.java │ │ ├── PropertyListMixin.java │ │ ├── ReadOnlyPropertyMixin.java │ │ ├── StateChangeMixin.java │ │ ├── TimeSynchronizationMixin.java │ │ ├── WritablePropertyOutOfServiceMixin.java │ │ └── event │ │ ├── AlertReportingMixin.java │ │ ├── AlgoReportingMixin.java │ │ ├── EventReportingMixin.java │ │ ├── IntrinsicReportingMixin.java │ │ ├── StateTransition.java │ │ ├── eventAlgo │ │ ├── BufferReadyAlgo.java │ │ ├── ChangeOfBitstringAlgo.java │ │ ├── ChangeOfLifeSafetyAlgo.java │ │ ├── ChangeOfStateAlgo.java │ │ ├── CommandFailureAlgo.java │ │ ├── EventAlgorithm.java │ │ ├── NoneAlgo.java │ │ ├── OutOfRangeAlgo.java │ │ └── UnsignedRangeAlgo.java │ │ └── faultAlgo │ │ ├── FaultAlgorithm.java │ │ ├── FaultLifeSafetyAlgo.java │ │ ├── FaultOutOfRangeAlgo.java │ │ └── FaultStateAlgo.java │ ├── persistence │ ├── FilePersistence.java │ ├── IPersistence.java │ └── NullPersistence.java │ ├── service │ ├── Service.java │ ├── VendorServiceKey.java │ ├── acknowledgement │ │ ├── AcknowledgementService.java │ │ ├── AtomicReadFileAck.java │ │ ├── AtomicWriteFileAck.java │ │ ├── ConfirmedPrivateTransferAck.java │ │ ├── CreateObjectAck.java │ │ ├── GetAlarmSummaryAck.java │ │ ├── GetEnrollmentSummaryAck.java │ │ ├── GetEventInformationAck.java │ │ ├── ReadPropertyAck.java │ │ ├── ReadPropertyMultipleAck.java │ │ ├── ReadRangeAck.java │ │ ├── VtDataAck.java │ │ └── VtOpenAck.java │ ├── confirmed │ │ ├── AcknowledgeAlarmRequest.java │ │ ├── AddListElementRequest.java │ │ ├── AtomicReadFileRequest.java │ │ ├── AtomicWriteFileRequest.java │ │ ├── ConfirmedCovNotificationMultipleRequest.java │ │ ├── ConfirmedCovNotificationRequest.java │ │ ├── ConfirmedEventNotificationRequest.java │ │ ├── ConfirmedPrivateTransferRequest.java │ │ ├── ConfirmedRequestService.java │ │ ├── ConfirmedTextMessageRequest.java │ │ ├── CreateObjectRequest.java │ │ ├── DeleteObjectRequest.java │ │ ├── DeviceCommunicationControlRequest.java │ │ ├── GetAlarmSummaryRequest.java │ │ ├── GetEnrollmentSummaryRequest.java │ │ ├── GetEventInformationRequest.java │ │ ├── LifeSafetyOperationRequest.java │ │ ├── ReadPropertyMultipleRequest.java │ │ ├── ReadPropertyRequest.java │ │ ├── ReadRangeRequest.java │ │ ├── ReinitializeDeviceRequest.java │ │ ├── RemoveListElementRequest.java │ │ ├── SubscribeCOVPropertyMultipleRequest.java │ │ ├── SubscribeCOVPropertyRequest.java │ │ ├── SubscribeCOVRequest.java │ │ ├── VtCloseRequest.java │ │ ├── VtDataRequest.java │ │ ├── VtOpenRequest.java │ │ ├── WritePropertyMultipleRequest.java │ │ └── WritePropertyRequest.java │ └── unconfirmed │ │ ├── IAmRequest.java │ │ ├── IHaveRequest.java │ │ ├── TimeSynchronizationRequest.java │ │ ├── UTCTimeSynchronizationRequest.java │ │ ├── UnconfirmedCovNotificationMultipleRequest.java │ │ ├── UnconfirmedCovNotificationRequest.java │ │ ├── UnconfirmedEventNotificationRequest.java │ │ ├── UnconfirmedPrivateTransferRequest.java │ │ ├── UnconfirmedRequestService.java │ │ ├── UnconfirmedTextMessageRequest.java │ │ ├── WhoHasRequest.java │ │ ├── WhoIsRequest.java │ │ └── WriteGroupRequest.java │ ├── transport │ ├── DefaultTransport.java │ ├── SegmentWindow.java │ ├── ServiceFutureImpl.java │ ├── Transport.java │ ├── UnackedMessageContext.java │ ├── UnackedMessageKey.java │ └── UnackedMessages.java │ ├── type │ ├── AmbiguousValue.java │ ├── DateMatchable.java │ ├── Encodable.java │ ├── EncodedValue.java │ ├── ObjectTypePropertyReference.java │ ├── TagData.java │ ├── ThreadLocalObjectTypePropertyReferenceStack.java │ ├── ThreadLocalObjectTypeStack.java │ ├── constructed │ │ ├── AccessRule.java │ │ ├── AccessThreatLevel.java │ │ ├── AccumulatorRecord.java │ │ ├── ActionCommand.java │ │ ├── ActionList.java │ │ ├── Address.java │ │ ├── AddressBinding.java │ │ ├── AssignedAccessRights.java │ │ ├── AssignedLandingCalls.java │ │ ├── AuthenticationFactor.java │ │ ├── AuthenticationFactorFormat.java │ │ ├── AuthenticationPolicy.java │ │ ├── BACnetArray.java │ │ ├── BDTEntry.java │ │ ├── BaseType.java │ │ ├── CalendarEntry.java │ │ ├── ChannelValue.java │ │ ├── Choice.java │ │ ├── ChoiceOptions.java │ │ ├── ClientCov.java │ │ ├── CovMultipleSubscription.java │ │ ├── CovSubscription.java │ │ ├── CredentialAuthenticationFactor.java │ │ ├── DailySchedule.java │ │ ├── DateRange.java │ │ ├── DateTime.java │ │ ├── DaysOfWeek.java │ │ ├── Destination.java │ │ ├── DeviceObjectPropertyReference.java │ │ ├── DeviceObjectPropertyValue.java │ │ ├── DeviceObjectReference.java │ │ ├── EventLogRecord.java │ │ ├── EventNotificationSubscription.java │ │ ├── EventTransitionBits.java │ │ ├── FDTEntry.java │ │ ├── FaultParameter.java │ │ ├── GroupChannelValue.java │ │ ├── HostAddress.java │ │ ├── HostNPort.java │ │ ├── KeyIdentifier.java │ │ ├── LandingCallStatus.java │ │ ├── LandingDoorStatus.java │ │ ├── LiftCarCallList.java │ │ ├── LightingCommand.java │ │ ├── LimitEnable.java │ │ ├── LogData.java │ │ ├── LogMultipleRecord.java │ │ ├── LogRecord.java │ │ ├── LogStatus.java │ │ ├── NameValue.java │ │ ├── NameValueCollection.java │ │ ├── NetworkSecurityPolicy.java │ │ ├── NetworkSourceAddress.java │ │ ├── ObjectPropertyReference.java │ │ ├── ObjectPropertyValue.java │ │ ├── ObjectTypesSupported.java │ │ ├── OptionalBinaryPV.java │ │ ├── OptionalCharacterString.java │ │ ├── OptionalReal.java │ │ ├── OptionalUnsigned.java │ │ ├── PortPermission.java │ │ ├── Prescale.java │ │ ├── PriorityArray.java │ │ ├── PriorityValue.java │ │ ├── ProcessIdSelection.java │ │ ├── PropertyAccessResult.java │ │ ├── PropertyReference.java │ │ ├── PropertyStates.java │ │ ├── PropertyValue.java │ │ ├── ReadAccessResult.java │ │ ├── ReadAccessSpecification.java │ │ ├── Recipient.java │ │ ├── RecipientProcess.java │ │ ├── ResultFlags.java │ │ ├── RouterEntry.java │ │ ├── Scale.java │ │ ├── SecurityKeySet.java │ │ ├── SequenceOf.java │ │ ├── ServicesSupported.java │ │ ├── SetpointReference.java │ │ ├── ShedLevel.java │ │ ├── SpecialEvent.java │ │ ├── StatusFlags.java │ │ ├── TimeStamp.java │ │ ├── TimeValue.java │ │ ├── TimerStateChangeValue.java │ │ ├── ValueSource.java │ │ ├── VmacEntry.java │ │ ├── VtSession.java │ │ ├── WeekNDay.java │ │ └── WriteAccessSpecification.java │ ├── enumerated │ │ ├── AbortReason.java │ │ ├── AccessAuthenticationFactorDisable.java │ │ ├── AccessCredentialDisable.java │ │ ├── AccessCredentialDisableReason.java │ │ ├── AccessEvent.java │ │ ├── AccessPassbackMode.java │ │ ├── AccessUserType.java │ │ ├── AccessZoneOccupancyState.java │ │ ├── Action.java │ │ ├── AuthenticationFactorType.java │ │ ├── AuthenticationStatus.java │ │ ├── AuthorizationExemption.java │ │ ├── AuthorizationMode.java │ │ ├── BackupState.java │ │ ├── BinaryLightingPV.java │ │ ├── BinaryPV.java │ │ ├── DeviceStatus.java │ │ ├── DoorAlarmState.java │ │ ├── DoorSecuredStatus.java │ │ ├── DoorStatus.java │ │ ├── DoorValue.java │ │ ├── EngineeringUnits.java │ │ ├── ErrorClass.java │ │ ├── ErrorCode.java │ │ ├── EscalatorFault.java │ │ ├── EscalatorMode.java │ │ ├── EscalatorOperationDirection.java │ │ ├── EventState.java │ │ ├── EventType.java │ │ ├── FaultType.java │ │ ├── FileAccessMethod.java │ │ ├── IPMode.java │ │ ├── LifeSafetyMode.java │ │ ├── LifeSafetyOperation.java │ │ ├── LifeSafetyState.java │ │ ├── LiftCarDirection.java │ │ ├── LiftCarDoorCommand.java │ │ ├── LiftCarDriveStatus.java │ │ ├── LiftCarMode.java │ │ ├── LiftFault.java │ │ ├── LiftGroupMode.java │ │ ├── LightingInProgress.java │ │ ├── LightingOperation.java │ │ ├── LightingTransition.java │ │ ├── LockStatus.java │ │ ├── LoggingType.java │ │ ├── Maintenance.java │ │ ├── MessagePriority.java │ │ ├── NetworkNumberQuality.java │ │ ├── NetworkPortCommand.java │ │ ├── NetworkType.java │ │ ├── NodeType.java │ │ ├── NotifyType.java │ │ ├── ObjectType.java │ │ ├── Polarity.java │ │ ├── ProgramError.java │ │ ├── ProgramRequest.java │ │ ├── ProgramState.java │ │ ├── PropertyIdentifier.java │ │ ├── ProtocolLevel.java │ │ ├── RejectReason.java │ │ ├── Relationship.java │ │ ├── Reliability.java │ │ ├── RestartReason.java │ │ ├── SecurityLevel.java │ │ ├── SecurityPolicy.java │ │ ├── Segmentation.java │ │ ├── ShedState.java │ │ ├── SilencedState.java │ │ ├── TimerState.java │ │ ├── TimerTransition.java │ │ ├── VtClass.java │ │ └── WriteStatus.java │ ├── error │ │ ├── BACnetError.java │ │ ├── BaseError.java │ │ ├── ChangeListError.java │ │ ├── ConfirmedPrivateTransferError.java │ │ ├── CreateObjectError.java │ │ ├── ErrorClassAndCode.java │ │ ├── SubscribeCovPropertyMultipleError.java │ │ ├── VTCloseError.java │ │ └── WritePropertyMultipleError.java │ ├── eventParameter │ │ ├── AbstractEventParameter.java │ │ ├── AccessEvent.java │ │ ├── BufferReady.java │ │ ├── ChangeOfBitString.java │ │ ├── ChangeOfCharacterString.java │ │ ├── ChangeOfDiscreteValue.java │ │ ├── ChangeOfLifeSafety.java │ │ ├── ChangeOfState.java │ │ ├── ChangeOfStatusFlags.java │ │ ├── ChangeOfTimer.java │ │ ├── ChangeOfValue.java │ │ ├── CommandFailure.java │ │ ├── DoubleOutOfRange.java │ │ ├── EventParameter.java │ │ ├── Extended.java │ │ ├── FloatingLimit.java │ │ ├── OutOfRange.java │ │ ├── SignedOutOfRange.java │ │ ├── UnsignedOutOfRange.java │ │ └── UnsignedRange.java │ ├── notificationParameters │ │ ├── AbstractNotificationParameter.java │ │ ├── AccessEventNotif.java │ │ ├── BufferReadyNotif.java │ │ ├── ChangeOfBitStringNotif.java │ │ ├── ChangeOfCharacterStringNotif.java │ │ ├── ChangeOfDiscreteValueNotif.java │ │ ├── ChangeOfLifeSafetyNotif.java │ │ ├── ChangeOfReliabilityNotif.java │ │ ├── ChangeOfStateNotif.java │ │ ├── ChangeOfStatusFlagsNotif.java │ │ ├── ChangeOfTimerNotif.java │ │ ├── ChangeOfValueNotif.java │ │ ├── CommandFailureNotif.java │ │ ├── ComplexEventTypeNotif.java │ │ ├── DoubleOutOfRangeNotif.java │ │ ├── ExtendedNotif.java │ │ ├── FloatingLimitNotif.java │ │ ├── NotificationParameters.java │ │ ├── OutOfRangeNotif.java │ │ ├── SignedOutOfRangeNotif.java │ │ ├── UnsignedOutOfRangeNotif.java │ │ └── UnsignedRangeNotif.java │ └── primitive │ │ ├── BitString.java │ │ ├── Boolean.java │ │ ├── CharacterString.java │ │ ├── Date.java │ │ ├── Double.java │ │ ├── Enumerated.java │ │ ├── Null.java │ │ ├── ObjectIdentifier.java │ │ ├── OctetString.java │ │ ├── Primitive.java │ │ ├── Real.java │ │ ├── SignedInteger.java │ │ ├── Time.java │ │ ├── Unsigned16.java │ │ ├── Unsigned32.java │ │ ├── Unsigned8.java │ │ └── UnsignedInteger.java │ └── util │ ├── BACnetUtils.java │ ├── BackupClient.java │ ├── DeviceObjectPropertyReferenceValues.java │ ├── DeviceObjectPropertyReferences.java │ ├── DeviceObjectPropertyValues.java │ ├── DiscoveryUtils.java │ ├── PropertyReferenceValues.java │ ├── PropertyReferences.java │ ├── PropertyUtils.java │ ├── PropertyValues.java │ ├── ReadListener.java │ ├── ReadListenerUpdater.java │ ├── RemoteDeviceDiscoverer.java │ ├── RemoteDeviceFinder.java │ ├── RemoteDeviceTimeoutCallback.java │ ├── RequestUtils.java │ ├── RestoreClient.java │ └── sero │ ├── ArrayUtils.java │ ├── ByteQueue.java │ ├── IpAddressUtils.java │ ├── IpWhiteListException.java │ ├── LineHandler.java │ ├── SerialPortWrapper.java │ ├── StreamUtils.java │ ├── ThreadUtils.java │ └── Utils.java └── test ├── java └── com │ └── serotonin │ └── bacnet4j │ ├── AbstractTest.java │ ├── AnnexFEncodingTest.java │ ├── LocalDeviceTest.java │ ├── MessagingTest.java │ ├── Mstp.java │ ├── RemoteDeviceTest.java │ ├── SetupTest.java │ ├── TestUtils.java │ ├── adhoc │ ├── BACnetIpUtils.java │ ├── DateRangeTest.java │ ├── IpMasterTest.java │ ├── MultipleLocalDevices.java │ ├── SchedulerTest.java │ └── rs485 │ │ ├── MasterTest.java │ │ └── PortTest.java │ ├── cache │ ├── CachePoliciesTest.java │ ├── RemoteEntityCachePolicyTest.java │ └── RemoteEntityCacheTest.java │ ├── npdu │ ├── NPCITest.java │ ├── NetworkPriorityTest.java │ ├── NetworkUtilsTest.java │ └── ip │ │ ├── BBMDTest.java │ │ ├── IpNetworkBuilderTest.java │ │ └── IpNetworkUtilsTest.java │ ├── obj │ ├── AccumulatorObjectTest.java │ ├── AlertEnrollmentObjectTest.java │ ├── AnalogInputObjectTest.java │ ├── AnalogOutputObjectTest.java │ ├── AnalogValueObjectTest.java │ ├── AveragingObjectTest.java │ ├── BACnetObjectListenerTest.java │ ├── BACnetObjectTest.java │ ├── BinaryInputObjectTest.java │ ├── BinaryOutputObjectTest.java │ ├── BinaryValueObjectTest.java │ ├── CalendarObjectTest.java │ ├── ChangeOfValueTest.java │ ├── CovNotifListener.java │ ├── DeviceObjectTest.java │ ├── EventEnrollmentObjectTest.java │ ├── EventLogObjectTest.java │ ├── EventNotifListener.java │ ├── FileObjectTest.java │ ├── GroupObjectTest.java │ ├── IntrinsicAlarmTest.java │ ├── LifeSafetyPointObjectTest.java │ ├── LifeSafetyZoneObjectTest.java │ ├── MultistateInputObjectTest.java │ ├── MultistateOutputObjectTest.java │ ├── MultistateValueObjectTest.java │ ├── NotificationClassObjectTest.java │ ├── NotificationForwarderObjectTest.java │ ├── ObjectPropertiesTest.java │ ├── PulseConverterObjectTest.java │ ├── ScheduleObjectTest.java │ ├── TrendLogMultipleObjectTest.java │ ├── TrendLogObjectTest.java │ └── mixin │ │ ├── CommandableMixinTest.java │ │ └── ObjectIdAndNameMixinTest.java │ ├── service │ ├── acknowledgement │ │ └── InvalidPropertyValueTest.java │ ├── confirmed │ │ ├── AddListElementRequestTest.java │ │ ├── AtomicReadFileRequestTest.java │ │ ├── AtomicWriteFileRequestTest.java │ │ ├── ConfirmedPrivateTransferRequestTest.java │ │ ├── ConfirmedRequestTest.java │ │ ├── ConfirmedTextMessageRequestTest.java │ │ ├── CreateObjectRequestTest.java │ │ ├── DeleteObjectRequestTest.java │ │ ├── DeviceCommunicationControlRequestTest.java │ │ ├── LifeSafetyOperationRequestTest.java │ │ ├── ReadPriorityArrayTest.java │ │ ├── ReadPropertyMultipleRequestTest.java │ │ ├── ReadPropertyRequestTest.java │ │ ├── ReadRangeRequestTest.java │ │ ├── ReinitializeDeviceRequestTest.java │ │ └── RemoveListElementRequestTest.java │ └── unconfirmed │ │ ├── AutoDiscoveryTest.java │ │ ├── TimeSynchronizationRequestTest.java │ │ ├── UTCTimeSynchronizationRequestTest.java │ │ ├── UnconfirmedPrivateTransferRequestTest.java │ │ └── UnconfirmedTextMessageRequestTest.java │ ├── transport │ └── DefaultTransportTest.java │ ├── type │ ├── EncodableAnyTest.java │ ├── EncodableTest.java │ ├── EncodedValueTest.java │ ├── constructed │ │ ├── BACnetArrayTest.java │ │ ├── DateRangeTest.java │ │ ├── DaysOfWeekTest.java │ │ ├── FaultParameterTest.java │ │ ├── NameValueTest.java │ │ ├── ReadAccessResultTest.java │ │ └── WeekNDayTest.java │ └── primitive │ │ ├── DateTest.java │ │ ├── RealTest.java │ │ ├── TimeTest.java │ │ └── UnsignedIntegerTest.java │ └── util │ ├── BackupRestoreTest.java │ ├── JsscSerialPortInputStream.java │ ├── JsscSerialPortOutputStream.java │ ├── PropertyUtilsTest.java │ ├── RemoteDeviceDiscovererTest.java │ ├── RemoteDeviceFinderTest.java │ └── RequestUtilsTest.java └── resources ├── backupTest.txt ├── fileObjectTest.txt ├── realtime-driver.properties └── simplelogger.properties /.github/workflows/sonarqube.yml: -------------------------------------------------------------------------------- 1 | name: SonarCloud 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | jobs: 9 | build: 10 | name: Build and analyze 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | - name: Set up JDK 11 17 | uses: actions/setup-java@v4 18 | with: 19 | java-version: 11 20 | distribution: 'zulu' 21 | cache: 'maven' 22 | - name: Cache SonarCloud packages 23 | uses: actions/cache@v3 24 | with: 25 | path: ~/.sonar/cache 26 | key: ${{ runner.os }}-sonar 27 | restore-keys: ${{ runner.os }}-sonar 28 | - name: Build and analyze 29 | env: 30 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 31 | run: mvn -B -T1C test-compile org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=RadixIoT_BACnet4J -Dsonar.organization=radixiot 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/NotificationClassListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j; 30 | 31 | import com.serotonin.bacnet4j.type.constructed.TimeStamp; 32 | import com.serotonin.bacnet4j.type.enumerated.EventState; 33 | import com.serotonin.bacnet4j.type.enumerated.EventType; 34 | import com.serotonin.bacnet4j.type.enumerated.NotifyType; 35 | import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters; 36 | import com.serotonin.bacnet4j.type.primitive.Boolean; 37 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 38 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 39 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 40 | 41 | /** 42 | * An internal (proprietary) mechanism for listening internally for event/alarm notifications via intrinsic 43 | * reporting. To use, implement this interface and add as a listener within a NotificationClassObject. 44 | * 45 | * @author Matthew 46 | */ 47 | public interface NotificationClassListener { 48 | /** 49 | * Calls to this method are made in internal threads that should not be blocked. If blocking is required, methods 50 | * such as LocalDevice.submit and LocalDevice.execute can be used to run code asynchronously. 51 | */ 52 | void event(ObjectIdentifier eventObjectIdentifier, TimeStamp timeStamp, UnsignedInteger notificationClass, 53 | UnsignedInteger priority, EventType eventType, CharacterString messageText, NotifyType notifyType, 54 | Boolean ackRequired, EventState fromState, EventState toState, NotificationParameters eventValues); 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/ResponseConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j; 30 | 31 | import com.serotonin.bacnet4j.apdu.AckAPDU; 32 | import com.serotonin.bacnet4j.exception.BACnetException; 33 | import com.serotonin.bacnet4j.service.acknowledgement.AcknowledgementService; 34 | 35 | public interface ResponseConsumer { 36 | void success(AcknowledgementService ack); 37 | 38 | void fail(AckAPDU ack); 39 | 40 | void ex(BACnetException e); 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/ResponseConsumerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j; 30 | 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | 34 | import com.serotonin.bacnet4j.apdu.AckAPDU; 35 | import com.serotonin.bacnet4j.exception.BACnetException; 36 | import com.serotonin.bacnet4j.service.acknowledgement.AcknowledgementService; 37 | 38 | abstract public class ResponseConsumerAdapter implements ResponseConsumer { 39 | static final Logger LOG = LoggerFactory.getLogger(ResponseConsumerAdapter.class); 40 | 41 | @SuppressWarnings("unchecked") 42 | @Override 43 | public final void success(AcknowledgementService ack) { 44 | ack((T) ack); 45 | } 46 | 47 | abstract public void ack(T ack); 48 | 49 | @Override 50 | public void fail(AckAPDU ack) { 51 | LOG.error("Request failed {}", ack); 52 | } 53 | 54 | @Override 55 | public void ex(BACnetException e) { 56 | LOG.error("Request failed", e); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/ServiceFuture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetException; 32 | import com.serotonin.bacnet4j.service.acknowledgement.AcknowledgementService; 33 | 34 | public interface ServiceFuture { 35 | T get() throws BACnetException; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/apdu/AckAPDU.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.apdu; 30 | 31 | abstract public class AckAPDU extends APDU { 32 | /** 33 | * This parameter shall be the 'invokeID' contained in the confirmed service request being acknowledged. The same 34 | * 'originalinvokeID' shall be used for all segments of a segmented acknowledgment. 35 | */ 36 | protected byte originalInvokeId; 37 | 38 | public byte getOriginalInvokeId() { 39 | return originalInvokeId; 40 | } 41 | 42 | public boolean isServer() { 43 | return true; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "AckAPDU [originalInvokeId=" + originalInvokeId + "]"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/apdu/Segmentable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.apdu; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetException; 32 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 33 | 34 | public interface Segmentable { 35 | byte getInvokeId(); 36 | 37 | boolean isSegmentedMessage(); 38 | 39 | boolean isMoreFollows(); 40 | 41 | int getSequenceNumber(); 42 | 43 | int getProposedWindowSize(); 44 | 45 | void appendServiceData(ByteQueue segmentable); 46 | 47 | void parseServiceData() throws BACnetException; 48 | 49 | ByteQueue getServiceData(); 50 | 51 | APDU clone(boolean moreFollows, int sequenceNumber, int actualSegWindow, ByteQueue data); 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/cache/CachedRemoteEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.cache; 30 | 31 | import com.serotonin.bacnet4j.LocalDevice; 32 | 33 | public class CachedRemoteEntity { 34 | private final T entity; 35 | private final RemoteEntityCachePolicy policy; 36 | private final Object cacheState; 37 | 38 | public CachedRemoteEntity(final LocalDevice localDevice, final T entity, final RemoteEntityCachePolicy policy) { 39 | this.entity = entity; 40 | this.policy = policy; 41 | this.cacheState = policy.prepareState(localDevice); 42 | } 43 | 44 | public boolean hasExpired(final LocalDevice localDevice) { 45 | return policy.hasExpired(localDevice, cacheState); 46 | } 47 | 48 | public T getEntity() { 49 | return entity; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/enums/MaxApduLength.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.enums; 30 | 31 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 32 | 33 | public enum MaxApduLength { 34 | UP_TO_50(0, 50), // MinimumMessageSize 35 | UP_TO_128(1, 128), // 36 | UP_TO_206(2, 206), // Fits in a LonTalk frame 37 | UP_TO_480(3, 480), // Fits in an ARCNET frame 38 | UP_TO_1024(4, 1024), // 39 | UP_TO_1476(5, 1476); // Fits in an ISO 8802-3 frame 40 | 41 | private byte id; 42 | private UnsignedInteger maxLength; 43 | 44 | MaxApduLength(final int id, final int maxLength) { 45 | this.id = (byte) id; 46 | this.maxLength = new UnsignedInteger(maxLength); 47 | } 48 | 49 | public byte getId() { 50 | return id; 51 | } 52 | 53 | public int getMaxLengthInt() { 54 | return maxLength.intValue(); 55 | } 56 | 57 | public UnsignedInteger getMaxLength() { 58 | return maxLength; 59 | } 60 | 61 | public static MaxApduLength valueOf(final byte id) { 62 | if (id == UP_TO_50.id) 63 | return UP_TO_50; 64 | if (id == UP_TO_128.id) 65 | return UP_TO_128; 66 | if (id == UP_TO_206.id) 67 | return UP_TO_206; 68 | if (id == UP_TO_480.id) 69 | return UP_TO_480; 70 | if (id == UP_TO_1024.id) 71 | return UP_TO_1024; 72 | if (id == UP_TO_1476.id) 73 | return UP_TO_1476; 74 | 75 | throw new IllegalArgumentException("Unknown id: " + id); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/enums/MaxSegments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.enums; 30 | 31 | public enum MaxSegments { 32 | UNSPECIFIED(0, Integer.MAX_VALUE), // 33 | UP_TO_2(1, 2), // 34 | UP_TO_4(2, 4), // 35 | UP_TO_8(3, 8), // 36 | UP_TO_16(4, 16), // 37 | UP_TO_32(5, 32), // 38 | UP_TO_64(6, 64), // 39 | MORE_THAN_64(7, Integer.MAX_VALUE), // 40 | ; 41 | 42 | private byte id; 43 | private int maxSegments; 44 | 45 | MaxSegments(int id, int maxSegments) { 46 | this.id = (byte) id; 47 | this.maxSegments = maxSegments; 48 | } 49 | 50 | public byte getId() { 51 | return id; 52 | } 53 | 54 | public int getMaxSegments() { 55 | return maxSegments; 56 | } 57 | 58 | public static MaxSegments valueOf(byte id) { 59 | if (id == UNSPECIFIED.id) 60 | return UNSPECIFIED; 61 | if (id == UP_TO_2.id) 62 | return UP_TO_2; 63 | if (id == UP_TO_4.id) 64 | return UP_TO_4; 65 | if (id == UP_TO_8.id) 66 | return UP_TO_8; 67 | if (id == UP_TO_16.id) 68 | return UP_TO_16; 69 | if (id == UP_TO_32.id) 70 | return UP_TO_32; 71 | if (id == UP_TO_64.id) 72 | return UP_TO_64; 73 | if (id == MORE_THAN_64.id) 74 | return MORE_THAN_64; 75 | 76 | throw new IllegalArgumentException("Unknown id: " + id); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/DefaultExceptionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.event; 30 | 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | 34 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 35 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 36 | 37 | public class DefaultExceptionListener implements ExceptionListener { 38 | static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionListener.class); 39 | 40 | @Override 41 | public void unimplementedVendorService(UnsignedInteger vendorId, UnsignedInteger serviceNumber, ByteQueue queue) { 42 | LOG.warn("Received unimplemented vendor service: vendor id={}, service number={}, bytes (with context id)=", 43 | vendorId, serviceNumber, queue); 44 | } 45 | 46 | @Override 47 | public void receivedException(Exception e) { 48 | LOG.error("", e); 49 | } 50 | 51 | @Override 52 | public void receivedThrowable(Throwable t) { 53 | LOG.error("", t); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/ExceptionDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.event; 30 | 31 | import java.util.List; 32 | import java.util.concurrent.CopyOnWriteArrayList; 33 | 34 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 35 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 36 | 37 | public class ExceptionDispatcher { 38 | private final List listeners = new CopyOnWriteArrayList<>(); 39 | private final ExceptionListener defaultExceptionListener = new DefaultExceptionListener(); 40 | 41 | public ExceptionDispatcher() { 42 | listeners.add(defaultExceptionListener); 43 | } 44 | 45 | public void addListener(final ExceptionListener l) { 46 | listeners.add(l); 47 | } 48 | 49 | public void removeListener(final ExceptionListener l) { 50 | listeners.remove(l); 51 | } 52 | 53 | public void removeDefaultExceptionListener() { 54 | listeners.remove(defaultExceptionListener); 55 | } 56 | 57 | public void fireUnimplementedVendorService(final UnsignedInteger vendorId, final UnsignedInteger serviceNumber, 58 | final ByteQueue queue) { 59 | for (final ExceptionListener l : listeners) 60 | l.unimplementedVendorService(vendorId, serviceNumber, queue); 61 | } 62 | 63 | public void fireReceivedException(final Exception e) { 64 | for (final ExceptionListener l : listeners) 65 | l.receivedException(e); 66 | } 67 | 68 | public void fireReceivedThrowable(final Throwable t) { 69 | for (final ExceptionListener l : listeners) 70 | l.receivedThrowable(t); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/ExceptionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.event; 30 | 31 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 32 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 33 | 34 | public interface ExceptionListener { 35 | void unimplementedVendorService(UnsignedInteger vendorId, UnsignedInteger serviceNumber, ByteQueue queue); 36 | 37 | void receivedException(Exception e); 38 | 39 | void receivedThrowable(Throwable t); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/IAmListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2019 Infinite Automation Software. All rights reserved. 3 | */ 4 | package com.serotonin.bacnet4j.event; 5 | 6 | import com.serotonin.bacnet4j.RemoteDevice; 7 | 8 | /** 9 | * @author Terry Packer 10 | * 11 | */ 12 | @FunctionalInterface 13 | public interface IAmListener extends DefaultDeviceEventListener { 14 | @Override 15 | void iAmReceived(RemoteDevice d); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/PrivateTransferHandler.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.event; 2 | 3 | import com.serotonin.bacnet4j.LocalDevice; 4 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 5 | import com.serotonin.bacnet4j.type.Encodable; 6 | import com.serotonin.bacnet4j.type.EncodedValue; 7 | import com.serotonin.bacnet4j.type.constructed.Address; 8 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 9 | 10 | public interface PrivateTransferHandler { 11 | Encodable handle(final LocalDevice localDevice, final Address from, final UnsignedInteger vendorId, 12 | final UnsignedInteger serviceNumber, final EncodedValue serviceParameters, boolean confirmed) 13 | throws BACnetErrorException; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/event/ReinitializeDeviceHandler.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.event; 2 | 3 | import com.serotonin.bacnet4j.LocalDevice; 4 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 5 | import com.serotonin.bacnet4j.service.confirmed.ReinitializeDeviceRequest.ReinitializedStateOfDevice; 6 | import com.serotonin.bacnet4j.type.constructed.Address; 7 | 8 | /** 9 | * Reinitialize device handler. By the time this object is called, the local device's password has already been 10 | * validated, and the indicated action should be carried out. 11 | * 12 | * @author Matthew 13 | */ 14 | public interface ReinitializeDeviceHandler { 15 | void handle(final LocalDevice localDevice, final Address from, 16 | final ReinitializedStateOfDevice reinitializedStateOfDevice) throws BACnetErrorException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/AbortAPDUException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.apdu.Abort; 32 | 33 | public class AbortAPDUException extends BACnetException { 34 | private static final long serialVersionUID = -1; 35 | 36 | private final Abort apdu; 37 | 38 | public AbortAPDUException(Abort apdu) { 39 | super(apdu.toString()); 40 | this.apdu = apdu; 41 | } 42 | 43 | public Abort getApdu() { 44 | return apdu; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetAbortException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Michel Seiler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.type.enumerated.AbortReason; 32 | 33 | public class BACnetAbortException extends BACnetException { 34 | private static final long serialVersionUID = -1; 35 | 36 | private final AbortReason abortReason; 37 | 38 | public BACnetAbortException(AbortReason abortReason) { 39 | super(abortReason.toString()); 40 | this.abortReason = abortReason; 41 | } 42 | 43 | public BACnetAbortException(AbortReason abortReason, Throwable cause) { 44 | super(abortReason.toString(), cause); 45 | this.abortReason = abortReason; 46 | } 47 | 48 | public AbortReason getAbortReason() { 49 | return abortReason; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class BACnetException extends Exception { 32 | private static final long serialVersionUID = -1; 33 | 34 | public BACnetException() { 35 | super(); 36 | } 37 | 38 | public BACnetException(String message, Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | public BACnetException(String message) { 43 | super(message); 44 | } 45 | 46 | public BACnetException(Throwable cause) { 47 | super(cause); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetRecoverableException.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.exception; 2 | 3 | public class BACnetRecoverableException extends BACnetException { 4 | private static final long serialVersionUID = 1L; 5 | 6 | public BACnetRecoverableException() { 7 | super(); 8 | } 9 | 10 | public BACnetRecoverableException(final String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetRejectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.type.enumerated.RejectReason; 32 | 33 | public class BACnetRejectException extends BACnetException { 34 | private static final long serialVersionUID = -1; 35 | 36 | private final RejectReason rejectReason; 37 | 38 | public BACnetRejectException(RejectReason rejectReason) { 39 | super(rejectReason.toString()); 40 | this.rejectReason = rejectReason; 41 | } 42 | 43 | public BACnetRejectException(RejectReason rejectReason, Throwable cause) { 44 | super(rejectReason.toString(), cause); 45 | this.rejectReason = rejectReason; 46 | } 47 | 48 | public RejectReason getRejectReason() { 49 | return rejectReason; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class BACnetRuntimeException extends RuntimeException { 32 | private static final long serialVersionUID = -1; 33 | 34 | public BACnetRuntimeException() { 35 | super(); 36 | } 37 | 38 | public BACnetRuntimeException(String message, Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | public BACnetRuntimeException(String message) { 43 | super(message); 44 | } 45 | 46 | public BACnetRuntimeException(Throwable cause) { 47 | super(cause); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetServiceException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 32 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 33 | 34 | public class BACnetServiceException extends Exception { 35 | private static final long serialVersionUID = -1; 36 | 37 | private final ErrorClass errorClass; 38 | private final ErrorCode errorCode; 39 | 40 | public BACnetServiceException(ErrorClass errorClass, ErrorCode errorCode) { 41 | this.errorClass = errorClass; 42 | this.errorCode = errorCode; 43 | } 44 | 45 | public BACnetServiceException(ErrorClass errorClass, ErrorCode errorCode, String message) { 46 | super(message); 47 | this.errorClass = errorClass; 48 | this.errorCode = errorCode; 49 | } 50 | 51 | public ErrorClass getErrorClass() { 52 | return errorClass; 53 | } 54 | 55 | public ErrorCode getErrorCode() { 56 | return errorCode; 57 | } 58 | 59 | public boolean equals(ErrorClass errorClass, ErrorCode errorCode) { 60 | return this.errorClass.equals(errorClass) && this.errorCode.equals(errorCode); 61 | } 62 | 63 | @Override 64 | public String getMessage() { 65 | String message = "class=" + errorClass + ", code=" + errorCode; 66 | String userDesc = super.getMessage(); 67 | if (userDesc != null) 68 | message += ", message=" + userDesc; 69 | return message; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/BACnetTimeoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class BACnetTimeoutException extends BACnetException { 32 | private static final long serialVersionUID = -1; 33 | 34 | public BACnetTimeoutException() { 35 | super(); 36 | } 37 | 38 | public BACnetTimeoutException(final String message, final Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | public BACnetTimeoutException(final String message) { 43 | super(message); 44 | } 45 | 46 | public BACnetTimeoutException(final Throwable cause) { 47 | super(cause); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/CommunicationDisabledException.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.exception; 2 | 3 | /** 4 | * Thrown when sending a confirmed request when communication has been disabled as the result of a 5 | * DeviceCommunicationControlRequest. 6 | */ 7 | public class CommunicationDisabledException extends BACnetException { 8 | private static final long serialVersionUID = 1L; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/ConfirmedRequestParseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class ConfirmedRequestParseException extends BACnetException { 32 | private static final long serialVersionUID = -1; 33 | 34 | private final int originalInvokeId; 35 | 36 | public ConfirmedRequestParseException(int originalInvokeId) { 37 | this.originalInvokeId = originalInvokeId; 38 | } 39 | 40 | public ConfirmedRequestParseException(int originalInvokeId, Throwable cause) { 41 | super(cause); 42 | this.originalInvokeId = originalInvokeId; 43 | } 44 | 45 | public int getOriginalInvokeId() { 46 | return originalInvokeId; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/ErrorAPDUException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.apdu.Error; 32 | import com.serotonin.bacnet4j.type.error.ErrorClassAndCode; 33 | 34 | public class ErrorAPDUException extends BACnetException { 35 | private static final long serialVersionUID = -1; 36 | 37 | private final Error apdu; 38 | 39 | public ErrorAPDUException(final Error apdu) { 40 | super(apdu.toString()); 41 | this.apdu = apdu; 42 | } 43 | 44 | public Error getApdu() { 45 | return apdu; 46 | } 47 | 48 | public ErrorClassAndCode getError() { 49 | return apdu.getError().getErrorClassAndCode(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/IllegalPduTypeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class IllegalPduTypeException extends BACnetRuntimeException { 32 | private static final long serialVersionUID = -1; 33 | 34 | public IllegalPduTypeException(String message) { 35 | super(message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/NotImplementedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class NotImplementedException extends BACnetException { 32 | private static final long serialVersionUID = -1; 33 | 34 | public NotImplementedException() { 35 | super(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/PropertyValueException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.type.error.ErrorClassAndCode; 32 | 33 | /** 34 | * @author Matthew Lohbihler 35 | */ 36 | public class PropertyValueException extends Exception { 37 | private static final long serialVersionUID = 1L; 38 | 39 | private final ErrorClassAndCode error; 40 | 41 | public PropertyValueException(ErrorClassAndCode error) { 42 | this.error = error; 43 | } 44 | 45 | public ErrorClassAndCode getError() { 46 | return error; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/ReflectionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class ReflectionException extends BACnetException { 32 | private static final long serialVersionUID = 1L; 33 | 34 | public ReflectionException(Throwable cause) { 35 | super(cause); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/RejectAPDUException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.apdu.Reject; 32 | 33 | public class RejectAPDUException extends BACnetException { 34 | private static final long serialVersionUID = -1; 35 | 36 | private final Reject apdu; 37 | 38 | public RejectAPDUException(Reject apdu) { 39 | super(apdu.toString()); 40 | this.apdu = apdu; 41 | } 42 | 43 | public Reject getApdu() { 44 | return apdu; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/SegmentedMessageAbortedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | import com.serotonin.bacnet4j.apdu.Abort; 32 | 33 | public class SegmentedMessageAbortedException extends BACnetException { 34 | private static final long serialVersionUID = -1; 35 | 36 | private final Abort abort; 37 | 38 | public SegmentedMessageAbortedException(Abort abort) { 39 | this.abort = abort; 40 | } 41 | 42 | public Abort getAbort() { 43 | return abort; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/exception/ServiceTooBigException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.exception; 30 | 31 | public class ServiceTooBigException extends BACnetException { 32 | private static final long serialVersionUID = 1L; 33 | 34 | public ServiceTooBigException(String message) { 35 | super(message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/MessageValidationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu; 30 | 31 | public class MessageValidationException extends Exception { 32 | private static final long serialVersionUID = -1; 33 | 34 | public MessageValidationException(String message) { 35 | super(message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/NetworkIdentifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu; 30 | 31 | abstract public class NetworkIdentifier { 32 | abstract public String getIdString(); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/ipv6/Ipv6NetworkBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu.ipv6; 30 | 31 | public class Ipv6NetworkBuilder { 32 | private final String multicastAddress; 33 | private int port = Ipv6Network.DEFAULT_PORT; 34 | private String localBindAddress = Ipv6Network.DEFAULT_BIND_ADDRESS; 35 | private int localNetworkNumber = 0; 36 | 37 | public Ipv6NetworkBuilder(String multicastAddress) { 38 | this.multicastAddress = multicastAddress; 39 | } 40 | 41 | public Ipv6NetworkBuilder port(int port) { 42 | this.port = port; 43 | return this; 44 | } 45 | 46 | public Ipv6NetworkBuilder localBindAddress(String localBindAddress) { 47 | this.localBindAddress = localBindAddress; 48 | return this; 49 | } 50 | 51 | public Ipv6NetworkBuilder localNetworkNumber(int localNetworkNumber) { 52 | this.localNetworkNumber = localNetworkNumber; 53 | return this; 54 | } 55 | 56 | public Ipv6Network build() { 57 | return new Ipv6Network(multicastAddress, port, localBindAddress, localNetworkNumber); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/mstp/FrameResponseListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu.mstp; 30 | 31 | public interface FrameResponseListener { 32 | void response(Frame frame); 33 | 34 | void timeout(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/mstp/MstpNetworkIdentifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu.mstp; 30 | 31 | import com.serotonin.bacnet4j.npdu.NetworkIdentifier; 32 | 33 | public class MstpNetworkIdentifier extends NetworkIdentifier { 34 | private final String commPortId; 35 | 36 | public MstpNetworkIdentifier(String commPortId) { 37 | this.commPortId = commPortId; 38 | } 39 | 40 | public String getCommPortId() { 41 | return commPortId; 42 | } 43 | 44 | @Override 45 | public String getIdString() { 46 | return commPortId; 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | final int prime = 31; 52 | int result = 1; 53 | result = prime * result + ((commPortId == null) ? 0 : commPortId.hashCode()); 54 | return result; 55 | } 56 | 57 | @Override 58 | public boolean equals(Object obj) { 59 | if (this == obj) 60 | return true; 61 | if (obj == null) 62 | return false; 63 | if (getClass() != obj.getClass()) 64 | return false; 65 | MstpNetworkIdentifier other = (MstpNetworkIdentifier) obj; 66 | if (commPortId == null) { 67 | if (other.commPortId != null) 68 | return false; 69 | } 70 | else if (!commPortId.equals(other.commPortId)) 71 | return false; 72 | return true; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/mstp/MstpNetworkUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu.mstp; 30 | 31 | import com.serotonin.bacnet4j.type.constructed.Address; 32 | import com.serotonin.bacnet4j.type.primitive.OctetString; 33 | 34 | public class MstpNetworkUtils { 35 | public static OctetString toOctetString(byte station) { 36 | return new OctetString(new byte[] { station }); 37 | } 38 | 39 | public static byte getMstpAddress(OctetString mac) { 40 | return mac.getBytes()[0]; 41 | } 42 | 43 | public static String toString(OctetString mac) { 44 | return Integer.toString(getMstpAddress(mac) & 0xff); 45 | } 46 | 47 | public static Address toAddress(byte station) { 48 | return new Address(toOctetString(station)); 49 | } 50 | 51 | public static Address toAddress(int networkNumber, byte station) { 52 | return new Address(networkNumber, toOctetString(station)); 53 | } 54 | 55 | public static Address toAddress(int station) { 56 | return new Address(toOctetString((byte) station)); 57 | } 58 | 59 | public static Address toAddress(int networkNumber, int station) { 60 | return new Address(networkNumber, toOctetString((byte) station)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/mstp/realtime/RealtimeDriver.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Infinite Automation Software. All rights reserved. 3 | */ 4 | package com.serotonin.bacnet4j.npdu.mstp.realtime; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.lang.ProcessBuilder.Redirect; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | /** 14 | * IOCTL JNA Wrapper To handle IOCTL calls to proprietary 15 | * Realtime MS/TP Driver 16 | * 17 | * @author Terry Packer 18 | */ 19 | public class RealtimeDriver { 20 | static final Logger LOG = LoggerFactory.getLogger(RealtimeDriver.class); 21 | 22 | private final File driver; 23 | private final File configProgram; 24 | 25 | public RealtimeDriver(File driver, File configProgram) { 26 | this.driver = driver; 27 | this.configProgram = configProgram; 28 | } 29 | 30 | /** 31 | * @param portId 32 | * @param baud 33 | * @param thisStation 34 | * @throws InterruptedException 35 | * @throws IOException 36 | */ 37 | public void configure(String portId, int baud, byte thisStation, int maxMaster, int maxInfoFrames, int usageTimeout) throws InterruptedException, IOException { 38 | //TODO Redirect output to LOGs 39 | //TODO Create a setuid wrapper to call insmod to load the driver if not running as root 40 | 41 | //modprobe the driver 42 | ProcessBuilder pb = new ProcessBuilder("insmod", 43 | driver.getAbsolutePath()); 44 | pb.redirectError(Redirect.INHERIT); 45 | pb.redirectOutput(Redirect.INHERIT); 46 | Process process = pb.start(); 47 | process.waitFor(); 48 | process.destroy(); 49 | 50 | //Configure the driver for the port 51 | pb = new ProcessBuilder(configProgram.getAbsolutePath(), 52 | "-d" + portId, 53 | "-b" + baud, 54 | "-t" + thisStation, 55 | "-m" + maxMaster, 56 | "-f" + maxInfoFrames, 57 | "-u" + usageTimeout); 58 | pb.redirectError(Redirect.INHERIT); 59 | pb.redirectOutput(Redirect.INHERIT); 60 | process = pb.start(); 61 | process.waitFor(); 62 | process.destroy(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/mstp/realtime/RealtimeDriverProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Infinite Automation Software. All rights reserved. 3 | */ 4 | package com.serotonin.bacnet4j.npdu.mstp.realtime; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | 12 | /** 13 | * TODO Describe what properties are required in the config file 14 | * 15 | * Class to hold the IOCTL Constants for the Realtime Driver 16 | * 17 | * @author Terry Packer 18 | */ 19 | public class RealtimeDriverProperties { 20 | 21 | private final Map constants; 22 | 23 | public RealtimeDriverProperties(InputStream propertiesStream) throws IOException { 24 | Properties properties = new Properties(); 25 | properties.load(propertiesStream); 26 | constants = new HashMap<>(); 27 | properties.forEach((key,value) ->{ 28 | constants.put((String)key, Integer.decode((String)value)); 29 | }); 30 | 31 | 32 | } 33 | 34 | public int getValue(String key) throws NumberFormatException { 35 | return constants.get(key); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/test/TestNetworkIdentifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.npdu.test; 30 | 31 | import com.serotonin.bacnet4j.npdu.NetworkIdentifier; 32 | 33 | public class TestNetworkIdentifier extends NetworkIdentifier { 34 | @Override 35 | public String getIdString() { 36 | return "test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/test/TestNetworkMap.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu.test; 2 | 3 | import java.util.Iterator; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | import com.serotonin.bacnet4j.type.constructed.Address; 8 | 9 | public class TestNetworkMap implements Iterable { 10 | private final Map instances = new ConcurrentHashMap<>(); 11 | 12 | public void add(final Address address, final TestNetwork network) { 13 | if (instances.containsKey(address)) 14 | throw new IllegalStateException("Network map already contains key " + address); 15 | instances.put(address, network); 16 | } 17 | 18 | public void remove(final Address address) { 19 | if (!instances.containsKey(address)) 20 | throw new IllegalStateException("Network map does not contain key " + address); 21 | instances.remove(address); 22 | } 23 | 24 | public TestNetwork get(final Address address) { 25 | return instances.get(address); 26 | } 27 | 28 | @Override 29 | public Iterator iterator() { 30 | return instances.values().iterator(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/npdu/test/TestNetworkUtils.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu.test; 2 | 3 | import com.serotonin.bacnet4j.type.constructed.Address; 4 | import com.serotonin.bacnet4j.type.constructed.NetworkSourceAddress; 5 | 6 | public class TestNetworkUtils { 7 | public static Address toAddress(final int id) { 8 | return new Address(new byte[] { (byte) id }); 9 | } 10 | 11 | public static NetworkSourceAddress toSourceAddress(final int id) { 12 | return new NetworkSourceAddress(Address.LOCAL_NETWORK, new byte[] { (byte) id }); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/BACnetObjectListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.obj; 30 | 31 | import com.serotonin.bacnet4j.type.Encodable; 32 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 33 | 34 | @FunctionalInterface 35 | public interface BACnetObjectListener { 36 | void propertyChange(PropertyIdentifier pid, Encodable oldValue, Encodable newValue); 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/LifeSafety.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj; 2 | 3 | import com.serotonin.bacnet4j.type.Encodable; 4 | import com.serotonin.bacnet4j.type.constructed.Address; 5 | import com.serotonin.bacnet4j.type.enumerated.LifeSafetyOperation; 6 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 7 | import com.serotonin.bacnet4j.type.enumerated.SilencedState; 8 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 9 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 10 | 11 | public interface LifeSafety { 12 | /** 13 | * Override as required. Default implementation implements minimal behaviour. 14 | * 15 | * @param from 16 | * @param requestingProcessIdentifier 17 | * @param requestingSource 18 | * @param request 19 | */ 20 | default void handleLifeSafetyOperation(final Address from, final UnsignedInteger requestingProcessIdentifier, 21 | final CharacterString requestingSource, final LifeSafetyOperation request) { 22 | if (request.equals(LifeSafetyOperation.silence)) { 23 | writePropertyInternal(PropertyIdentifier.silenced, SilencedState.allSilenced); 24 | } else if (request.equals(LifeSafetyOperation.silenceAudible)) { 25 | writePropertyInternal(PropertyIdentifier.silenced, SilencedState.audibleSilenced); 26 | } else if (request.equals(LifeSafetyOperation.silenceVisual)) { 27 | writePropertyInternal(PropertyIdentifier.silenced, SilencedState.visibleSilenced); 28 | } else if (request.isOneOf(LifeSafetyOperation.unsilence, LifeSafetyOperation.unsilenceAudible, 29 | LifeSafetyOperation.unsilenceVisual)) { 30 | writePropertyInternal(PropertyIdentifier.silenced, SilencedState.unsilenced); 31 | } 32 | } 33 | 34 | BACnetObject writePropertyInternal(final PropertyIdentifier pid, final Encodable value); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/ObjectPropertyTypeDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.obj; 30 | 31 | import com.serotonin.bacnet4j.type.enumerated.ObjectType; 32 | 33 | public class ObjectPropertyTypeDefinition { 34 | private final ObjectType objectType; 35 | private final boolean required; 36 | private final PropertyTypeDefinition propertyTypeDefinition; 37 | 38 | public ObjectPropertyTypeDefinition(final ObjectType objectType, final boolean required, 39 | final PropertyTypeDefinition propertyTypeDefinition) { 40 | this.objectType = objectType; 41 | this.required = required; 42 | this.propertyTypeDefinition = propertyTypeDefinition; 43 | } 44 | 45 | public ObjectType getObjectType() { 46 | return objectType; 47 | } 48 | 49 | public PropertyTypeDefinition getPropertyTypeDefinition() { 50 | return propertyTypeDefinition; 51 | } 52 | 53 | public boolean isRequired() { 54 | return required; 55 | } 56 | 57 | public boolean isOptional() { 58 | return !required; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/fileAccess/RecordAccess.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.fileAccess; 2 | 3 | import java.io.IOException; 4 | 5 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 6 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 7 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 8 | import com.serotonin.bacnet4j.type.enumerated.FileAccessMethod; 9 | import com.serotonin.bacnet4j.type.primitive.OctetString; 10 | 11 | public interface RecordAccess extends FileAccess { 12 | @Override 13 | default FileAccessMethod getAccessMethod() { 14 | return FileAccessMethod.recordAccess; 15 | } 16 | 17 | @Override 18 | default boolean supportsStreamAccess() { 19 | return false; 20 | } 21 | 22 | @Override 23 | default OctetString readData(final long start, final long length) throws IOException, BACnetServiceException { 24 | throw new BACnetServiceException(ErrorClass.services, ErrorCode.invalidFileAccessMethod); 25 | } 26 | 27 | @Override 28 | default long writeData(final long start, final OctetString data) throws IOException, BACnetServiceException { 29 | throw new BACnetServiceException(ErrorClass.services, ErrorCode.invalidFileAccessMethod); 30 | } 31 | 32 | @Override 33 | default boolean supportsRecordAccess() { 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/logBuffer/ILogRecord.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.logBuffer; 2 | 3 | import com.serotonin.bacnet4j.service.confirmed.ReadRangeRequest.Sequenced; 4 | import com.serotonin.bacnet4j.service.confirmed.ReadRangeRequest.Timestamped; 5 | 6 | /** 7 | * An interface that represents the various objects that can be stored in a log buffer, including LogRecord, 8 | * LogMultipleRecord, and EventLogRecord. 9 | */ 10 | public interface ILogRecord extends Timestamped, Sequenced { 11 | // Placeholder 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/logBuffer/LinkedListLogBuffer.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.logBuffer; 2 | 3 | import java.util.LinkedList; 4 | 5 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 6 | 7 | public class LinkedListLogBuffer extends LogBuffer { 8 | private final LinkedList list = new LinkedList<>(); 9 | 10 | @Override 11 | public int size() { 12 | return list.size(); 13 | } 14 | 15 | @Override 16 | public void clear() { 17 | list.clear(); 18 | } 19 | 20 | @Override 21 | public void add(final T record) { 22 | list.add(record); 23 | } 24 | 25 | @Override 26 | public void remove() { 27 | list.removeFirst(); 28 | } 29 | 30 | @Override 31 | public T get(final int index) { 32 | return list.get(index); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "LinkedListLogBuffer" + list; 38 | } 39 | 40 | @Override 41 | public void validate() throws BACnetServiceException { 42 | //Not written, validation not necessary 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/logBuffer/LogBuffer.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.logBuffer; 2 | 3 | import com.serotonin.bacnet4j.service.confirmed.ReadRangeRequest.RangeReadable; 4 | import com.serotonin.bacnet4j.type.Encodable; 5 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 6 | 7 | /** 8 | * Base class for all implementations of log buffers. The class extends Encodable so that it can be one of its host 9 | * object's properties, but the property is not network readable. It's elements, however, are network readable via the 10 | * ReadRange request. 11 | * 12 | * TODO a disk-based log buffer might be nice. 13 | * 14 | * @author Matthew 15 | */ 16 | abstract public class LogBuffer extends Encodable implements RangeReadable { 17 | @Override 18 | public void write(final ByteQueue queue) { 19 | throw new RuntimeException("not actually encodable"); 20 | } 21 | 22 | @Override 23 | public void write(final ByteQueue queue, final int contextId) { 24 | throw new RuntimeException("not actually encodable"); 25 | } 26 | 27 | /** 28 | * Returns the current size of the buffer. 29 | */ 30 | @Override 31 | abstract public int size(); 32 | 33 | /** 34 | * Clears the buffer of all of its records. 35 | */ 36 | abstract public void clear(); 37 | 38 | /** 39 | * Adds the given record to the buffer 40 | */ 41 | abstract public void add(E record); 42 | 43 | /** 44 | * Removes the oldest record from the buffer, or does nothing if the buffer is empty. 45 | */ 46 | abstract public void remove(); 47 | 48 | /** 49 | * Returns the record at the given index where 0 is the oldest. 50 | */ 51 | @Override 52 | abstract public E get(int index); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/mixin/ReadOnlyPropertyMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.obj.mixin; 30 | 31 | import java.util.HashSet; 32 | import java.util.Set; 33 | 34 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 35 | import com.serotonin.bacnet4j.obj.AbstractMixin; 36 | import com.serotonin.bacnet4j.obj.BACnetObject; 37 | import com.serotonin.bacnet4j.type.constructed.PropertyValue; 38 | import com.serotonin.bacnet4j.type.constructed.ValueSource; 39 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 40 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 41 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 42 | 43 | /** 44 | * Prevents writing to the given properties. 45 | * 46 | * @author Matthew 47 | */ 48 | public class ReadOnlyPropertyMixin extends AbstractMixin { 49 | private final Set pids = new HashSet<>(); 50 | 51 | public ReadOnlyPropertyMixin(final BACnetObject bo, final PropertyIdentifier... pids) { 52 | super(bo); 53 | for (final PropertyIdentifier pid : pids) 54 | this.pids.add(pid); 55 | } 56 | 57 | @Override 58 | protected boolean validateProperty(final ValueSource valueSource, final PropertyValue value) 59 | throws BACnetServiceException { 60 | if (pids.contains(value.getPropertyIdentifier())) 61 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.writeAccessDenied); 62 | return false; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/mixin/StateChangeMixin.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.mixin; 2 | 3 | import java.util.Objects; 4 | 5 | import com.serotonin.bacnet4j.obj.AbstractMixin; 6 | import com.serotonin.bacnet4j.obj.BACnetObject; 7 | import com.serotonin.bacnet4j.type.Encodable; 8 | import com.serotonin.bacnet4j.type.constructed.DateTime; 9 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 10 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 11 | 12 | /** 13 | * Mixin that manages the following properties: 14 | * - change-of-state-time 15 | * - change-of-state-count 16 | * - time-of-state-count-reset 17 | * 18 | * @author Matthew 19 | */ 20 | public class StateChangeMixin extends AbstractMixin { 21 | public StateChangeMixin(final BACnetObject bo) { 22 | super(bo); 23 | 24 | // Default the values. 25 | writePropertyInternal(PropertyIdentifier.changeOfStateTime, DateTime.UNSPECIFIED); 26 | writePropertyInternal(PropertyIdentifier.changeOfStateCount, UnsignedInteger.ZERO); 27 | writePropertyInternal(PropertyIdentifier.timeOfStateCountReset, new DateTime(getLocalDevice())); 28 | } 29 | 30 | @Override 31 | protected void afterWriteProperty(final PropertyIdentifier pid, final Encodable oldValue, 32 | final Encodable newValue) { 33 | if (pid.equals(PropertyIdentifier.presentValue)) { 34 | if (!Objects.equals(oldValue, newValue)) { 35 | writePropertyInternal(PropertyIdentifier.changeOfStateTime, new DateTime(getLocalDevice())); 36 | final UnsignedInteger changeOfStateCount = get(PropertyIdentifier.changeOfStateCount); 37 | writePropertyInternal(PropertyIdentifier.changeOfStateCount, changeOfStateCount.increment16()); 38 | } 39 | } else if (pid.equals(PropertyIdentifier.changeOfStateCount)) { 40 | final UnsignedInteger changeOfStateCount = (UnsignedInteger) newValue; 41 | if (changeOfStateCount.intValue() == 0) { 42 | writePropertyInternal(PropertyIdentifier.timeOfStateCountReset, new DateTime(getLocalDevice())); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/mixin/event/StateTransition.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj.mixin.event; 2 | 3 | import com.serotonin.bacnet4j.type.enumerated.EventState; 4 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 5 | 6 | public class StateTransition { 7 | private final EventState toState; 8 | private final UnsignedInteger delay; 9 | 10 | public StateTransition(final EventState toState, final UnsignedInteger delay) { 11 | this.toState = toState; 12 | this.delay = delay; 13 | } 14 | 15 | public EventState getToState() { 16 | return toState; 17 | } 18 | 19 | public UnsignedInteger getDelay() { 20 | return delay; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "StateTransition [toState=" + toState + ", delay=" + delay + "]"; 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | final int prime = 31; 31 | int result = 1; 32 | result = prime * result + (delay == null ? 0 : delay.hashCode()); 33 | result = prime * result + (toState == null ? 0 : toState.hashCode()); 34 | return result; 35 | } 36 | 37 | @Override 38 | public boolean equals(final Object obj) { 39 | if (this == obj) 40 | return true; 41 | if (obj == null) 42 | return false; 43 | if (getClass() != obj.getClass()) 44 | return false; 45 | final StateTransition other = (StateTransition) obj; 46 | if (delay == null) { 47 | if (other.delay != null) 48 | return false; 49 | } else if (!delay.equals(other.delay)) 50 | return false; 51 | if (toState == null) { 52 | if (other.toState != null) 53 | return false; 54 | } else if (!toState.equals(other.toState)) 55 | return false; 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/obj/mixin/event/faultAlgo/FaultAlgorithm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.obj.mixin.event.faultAlgo; 30 | 31 | import java.util.Map; 32 | 33 | import com.serotonin.bacnet4j.obj.BACnetObject; 34 | import com.serotonin.bacnet4j.type.Encodable; 35 | import com.serotonin.bacnet4j.type.constructed.FaultParameter.AbstractFaultParameter; 36 | import com.serotonin.bacnet4j.type.constructed.ObjectPropertyReference; 37 | import com.serotonin.bacnet4j.type.enumerated.Reliability; 38 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 39 | 40 | abstract public class FaultAlgorithm { 41 | // Intrinsic reporting 42 | abstract public Reliability evaluateIntrinsic(Encodable oldMonitoredValue, Encodable newMonitoredValue, 43 | BACnetObject bo); 44 | 45 | // Algorithmic reporting 46 | abstract public Reliability evaluateAlgorithmic(Encodable oldMonitoredValue, Encodable newMonitoredValue, 47 | Reliability currentReliability, ObjectIdentifier monitoredObjectReference, 48 | Map additionalValues, AbstractFaultParameter parameters); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/persistence/FilePersistence.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.persistence; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.FileWriter; 7 | import java.io.IOException; 8 | import java.util.Properties; 9 | 10 | public class FilePersistence implements IPersistence { 11 | private final File file; 12 | private final Properties props; 13 | 14 | public FilePersistence(final File file) throws IOException { 15 | this.file = file; 16 | 17 | props = new Properties(); 18 | try { 19 | try (FileReader in = new FileReader(file)) { 20 | props.load(in); 21 | } 22 | } catch (@SuppressWarnings("unused") final FileNotFoundException e) { 23 | // no op. 24 | } 25 | } 26 | 27 | @Override 28 | public void save(final String key, final String value) { 29 | props.setProperty(key, value); 30 | store(); 31 | } 32 | 33 | @Override 34 | public String load(final String key) { 35 | return props.getProperty(key); 36 | } 37 | 38 | @Override 39 | public void remove(final String key) { 40 | props.remove(key); 41 | store(); 42 | } 43 | 44 | private void store() { 45 | try { 46 | try (FileWriter out = new FileWriter(file)) { 47 | props.store(out, ""); 48 | } 49 | } catch (final IOException e) { 50 | throw new RuntimeException(e); 51 | } 52 | } 53 | 54 | @Override 55 | public File[] getFiles() { 56 | return new File[] { file }; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/persistence/IPersistence.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.persistence; 2 | 3 | import java.io.File; 4 | 5 | import com.serotonin.bacnet4j.exception.BACnetException; 6 | import com.serotonin.bacnet4j.exception.BACnetRuntimeException; 7 | import com.serotonin.bacnet4j.type.Encodable; 8 | import com.serotonin.bacnet4j.type.constructed.SequenceOf; 9 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 10 | 11 | public interface IPersistence { 12 | void save(String key, String value); 13 | 14 | default void saveEncodable(final String key, final Encodable value) { 15 | final ByteQueue queue = new ByteQueue(); 16 | value.write(queue); 17 | save(key, queue.toHexString()); 18 | } 19 | 20 | String load(String key); 21 | 22 | default T loadEncodable(final String key, final Class clazz) { 23 | final String value = load(key); 24 | if (value == null) 25 | return null; 26 | final ByteQueue queue = new ByteQueue(value); 27 | try { 28 | return Encodable.read(queue, clazz); 29 | } catch (final BACnetException e) { 30 | throw new BACnetRuntimeException(e); 31 | } 32 | } 33 | 34 | default SequenceOf loadSequenceOf(final String key, final Class clazz) { 35 | final String value = load(key); 36 | if (value == null) 37 | return null; 38 | final ByteQueue queue = new ByteQueue(value); 39 | try { 40 | return Encodable.readSequenceOf(queue, clazz); 41 | } catch (final BACnetException e) { 42 | throw new BACnetRuntimeException(e); 43 | } 44 | } 45 | 46 | void remove(String key); 47 | 48 | /** 49 | * Provide the list of persistence files, if any, for backups. 50 | * 51 | * @return list of file, or null. 52 | */ 53 | default File[] getFiles() { 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/persistence/NullPersistence.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.persistence; 2 | 3 | /** 4 | * Implementation of {@link IPersistence} that does nothing. Allows the implementations to carry all of the required 5 | * method instead of having to have them all in LocalDevice by setting this instead of null. 6 | * 7 | * @author Matthew 8 | */ 9 | public class NullPersistence implements IPersistence { 10 | @Override 11 | public void save(final String key, final String value) { 12 | // no op 13 | } 14 | 15 | @Override 16 | public String load(final String key) { 17 | return null; 18 | } 19 | 20 | @Override 21 | public void remove(final String key) { 22 | // no op 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/service/Service.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.service; 30 | 31 | import com.serotonin.bacnet4j.npdu.NPCI.NetworkPriority; 32 | import com.serotonin.bacnet4j.type.constructed.BaseType; 33 | 34 | abstract public class Service extends BaseType { 35 | abstract public byte getChoiceId(); 36 | 37 | public NetworkPriority getNetworkPriority() { 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/DateMatchable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type; 30 | 31 | import com.serotonin.bacnet4j.type.primitive.Date; 32 | 33 | public interface DateMatchable { 34 | boolean matches(Date that); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/TagData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type; 30 | 31 | public class TagData { 32 | public int tagNumber; 33 | public boolean contextSpecific; 34 | public long length; 35 | public int tagLength; 36 | 37 | public int getTotalLength() { 38 | return (int) (length + tagLength); 39 | } 40 | 41 | public boolean isStartTag() { 42 | return contextSpecific && ((length & 6) == 6); 43 | } 44 | 45 | public boolean isStartTag(int contextId) { 46 | return isStartTag() && tagNumber == contextId; 47 | } 48 | 49 | public boolean isEndTag() { 50 | return contextSpecific && ((length & 7) == 7); 51 | } 52 | 53 | public boolean isEndTag(int contextId) { 54 | return isEndTag() && tagNumber == contextId; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/ThreadLocalObjectTypePropertyReferenceStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | public class ThreadLocalObjectTypePropertyReferenceStack { 35 | private static ThreadLocal> objTypePropRef = new ThreadLocal<>(); 36 | 37 | public static void set(final ObjectTypePropertyReference objectTypePropertyReference) { 38 | List stack = objTypePropRef.get(); 39 | 40 | if (stack == null) { 41 | stack = new ArrayList<>(); 42 | objTypePropRef.set(stack); 43 | } 44 | 45 | stack.add(objectTypePropertyReference); 46 | } 47 | 48 | public static ObjectTypePropertyReference get() { 49 | final List stack = objTypePropRef.get(); 50 | if (stack == null) 51 | return null; 52 | return stack.get(stack.size() - 1); 53 | } 54 | 55 | public static void remove() { 56 | final List stack = objTypePropRef.get(); 57 | if (stack == null) 58 | return; 59 | 60 | if (stack.size() <= 1) 61 | objTypePropRef.remove(); 62 | else 63 | stack.remove(stack.size() - 1); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/ThreadLocalObjectTypeStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | import com.serotonin.bacnet4j.type.enumerated.ObjectType; 35 | 36 | public class ThreadLocalObjectTypeStack { 37 | private static ThreadLocal> objType = new ThreadLocal<>(); 38 | 39 | public static void set(final ObjectType objectType) { 40 | List stack = objType.get(); 41 | 42 | if (stack == null) { 43 | stack = new ArrayList<>(); 44 | objType.set(stack); 45 | } 46 | 47 | stack.add(objectType); 48 | } 49 | 50 | public static ObjectType get() { 51 | final List stack = objType.get(); 52 | if (stack == null) 53 | return null; 54 | return stack.get(stack.size() - 1); 55 | } 56 | 57 | public static void remove() { 58 | final List stack = objType.get(); 59 | if (stack == null) 60 | return; 61 | 62 | if (stack.size() <= 1) 63 | objType.remove(); 64 | else 65 | stack.remove(stack.size() - 1); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/AccessThreatLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 32 | 33 | public class AccessThreatLevel extends UnsignedInteger { 34 | public AccessThreatLevel(final int value) { 35 | super(value); 36 | if (value < 0 || value > 100) 37 | throw new IllegalArgumentException("value must be between 0 and 100 inclusive. Given " + value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/BaseType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 32 | import com.serotonin.bacnet4j.type.Encodable; 33 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 34 | 35 | /** 36 | * Base type for constructed data types, as opposed to primitives. 37 | * 38 | * @author Matthew 39 | */ 40 | abstract public class BaseType extends Encodable { 41 | @Override 42 | public void write(final ByteQueue queue, final int contextId) { 43 | // Write a start tag 44 | writeContextTag(queue, contextId, true); 45 | write(queue); 46 | // Write an end tag 47 | writeContextTag(queue, contextId, false); 48 | } 49 | 50 | @Override 51 | public void validate() throws BACnetServiceException { 52 | //NO Op 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/EventTransitionBits.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.enumerated.EventState; 33 | import com.serotonin.bacnet4j.type.primitive.BitString; 34 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 35 | 36 | public class EventTransitionBits extends BitString { 37 | public EventTransitionBits(final boolean toOffnormal, final boolean toFault, final boolean toNormal) { 38 | super(new boolean[] { toOffnormal, toFault, toNormal }); 39 | } 40 | 41 | public EventTransitionBits(final ByteQueue queue) throws BACnetErrorException { 42 | super(queue); 43 | } 44 | 45 | public EventTransitionBits(final EventTransitionBits that) { 46 | super(that); 47 | } 48 | 49 | public boolean isToOffnormal() { 50 | return getValue()[0]; 51 | } 52 | 53 | public boolean isToFault() { 54 | return getValue()[1]; 55 | } 56 | 57 | public boolean isToNormal() { 58 | return getValue()[2]; 59 | } 60 | 61 | public boolean contains(final EventState toState) { 62 | return getValue(toState.getTransitionIndex()); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "EventTransitionBits [to-offnormal=" + isToOffnormal() + ", to-fault=" + isToFault() + ", to-normal=" + isToNormal() + "]"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/LimitEnable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.primitive.BitString; 33 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 34 | 35 | public class LimitEnable extends BitString { 36 | public LimitEnable(final boolean lowLimitEnable, final boolean highLimitEnable) { 37 | super(new boolean[] { lowLimitEnable, highLimitEnable }); 38 | } 39 | 40 | public LimitEnable(final ByteQueue queue) throws BACnetErrorException { 41 | super(queue); 42 | } 43 | 44 | public boolean isLowLimitEnable() { 45 | return getValue()[0]; 46 | } 47 | 48 | public boolean isHighLimitEnable() { 49 | return getValue()[1]; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return "LimitEnable [low-limit-enable=" + isLowLimitEnable() + ", high-limit-enable=" + isHighLimitEnable() + "]"; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/LogStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.primitive.BitString; 33 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 34 | 35 | public class LogStatus extends BitString { 36 | public LogStatus(final boolean logDisabled, final boolean bufferPurged, final boolean logInterrupted) { 37 | super(new boolean[] { logDisabled, bufferPurged, logInterrupted }); 38 | } 39 | 40 | public LogStatus(final ByteQueue queue) throws BACnetErrorException { 41 | super(queue); 42 | } 43 | 44 | public boolean isLogDisabled() { 45 | return getValue()[0]; 46 | } 47 | 48 | public boolean isBufferPurged() { 49 | return getValue()[1]; 50 | } 51 | 52 | public boolean isLogInterrupted() { 53 | return getValue()[2]; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "LogStatus [log-disabled=" + isLogDisabled() + ", buffer-purged=" + isBufferPurged() + ", log-interrupted=" + isLogInterrupted() + "]"; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/NetworkSourceAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.radixiot.com for commercial license options. 26 | * 27 | * @author Terry Packer 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.type.primitive.OctetString; 32 | import com.serotonin.bacnet4j.type.primitive.Unsigned16; 33 | 34 | /** 35 | * Marker class to indicate that the address was received 36 | * in the NPDU as the 'Source Address' 37 | */ 38 | public class NetworkSourceAddress extends Address { 39 | 40 | public NetworkSourceAddress(int sourceNetwork, byte[] sourceAddress) { 41 | super(sourceNetwork, sourceAddress); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return super.toString(); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | return super.hashCode(); 52 | } 53 | 54 | @Override 55 | public boolean equals(final Object obj) { 56 | return super.equals(obj); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/ObjectTypesSupported.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.enumerated.ObjectType; 33 | import com.serotonin.bacnet4j.type.primitive.BitString; 34 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 35 | 36 | public class ObjectTypesSupported extends BitString { 37 | public ObjectTypesSupported() { 38 | super(new boolean[60]); 39 | } 40 | 41 | public ObjectTypesSupported(final ByteQueue queue) throws BACnetErrorException { 42 | super(queue); 43 | } 44 | 45 | public boolean is(final ObjectType objectType) { 46 | return getArrayValue(objectType.intValue()); 47 | } 48 | 49 | public void set(final ObjectType objectType, final boolean supported) { 50 | getValue()[objectType.intValue()] = supported; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/ResultFlags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.primitive.BitString; 33 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 34 | 35 | public class ResultFlags extends BitString { 36 | public ResultFlags(final boolean firstItem, final boolean lastItem, final boolean moreItems) { 37 | super(new boolean[] { firstItem, lastItem, moreItems }); 38 | } 39 | 40 | public ResultFlags(final ByteQueue queue) throws BACnetErrorException { 41 | super(queue); 42 | } 43 | 44 | public boolean isFirstItem() { 45 | return getValue()[0]; 46 | } 47 | 48 | public boolean isLastItem() { 49 | return getValue()[1]; 50 | } 51 | 52 | public boolean isMoreItems() { 53 | return getValue()[2]; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "ResultFlags [first-item=" + isFirstItem() + ", last-item=" + isLastItem() + ", more-items=" + isMoreItems() + "]"; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/constructed/StatusFlags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.constructed; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.type.primitive.BitString; 33 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 34 | 35 | public class StatusFlags extends BitString { 36 | public StatusFlags(final boolean inAlarm, final boolean fault, final boolean overridden, 37 | final boolean outOfService) { 38 | super(new boolean[] { inAlarm, fault, overridden, outOfService }); 39 | } 40 | 41 | public StatusFlags(final ByteQueue queue) throws BACnetErrorException { 42 | super(queue); 43 | } 44 | 45 | public boolean isInAlarm() { 46 | return getValue()[0]; 47 | } 48 | 49 | public void setInAlarm(final boolean b) { 50 | getValue()[0] = b; 51 | } 52 | 53 | public boolean isFault() { 54 | return getValue()[1]; 55 | } 56 | 57 | public void setFault(final boolean b) { 58 | getValue()[1] = b; 59 | } 60 | 61 | public boolean isOverridden() { 62 | return getValue()[2]; 63 | } 64 | 65 | public void setOverridden(final boolean b) { 66 | getValue()[2] = b; 67 | } 68 | 69 | public boolean isOutOfService() { 70 | return getValue()[3]; 71 | } 72 | 73 | public void setOutOfService(final boolean b) { 74 | getValue()[3] = b; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "StatusFlags [in-alarm=" + isInAlarm() + ", fault=" + isFault() + ", overridden=" + isOverridden() + ", out-of-service=" + isOutOfService() + "]"; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/eventParameter/AbstractEventParameter.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.eventParameter; 2 | 3 | import com.serotonin.bacnet4j.obj.mixin.event.eventAlgo.EventAlgorithm; 4 | import com.serotonin.bacnet4j.type.constructed.BaseType; 5 | import com.serotonin.bacnet4j.type.constructed.DeviceObjectPropertyReference; 6 | import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters; 7 | 8 | abstract public class AbstractEventParameter extends BaseType { 9 | abstract public EventAlgorithm createEventAlgorithm(); 10 | 11 | /** 12 | * Override as required to update event parameters following a notification. 13 | * 14 | * @param notifParams 15 | */ 16 | public void postNotification(final NotificationParameters notifParams) { 17 | // no op 18 | } 19 | 20 | /** 21 | * Override as required to return a reference property if the subclass has one. 22 | * 23 | * @return the property reference. 24 | */ 25 | public DeviceObjectPropertyReference getReference() { 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/notificationParameters/AbstractNotificationParameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.notificationParameters; 30 | 31 | import com.serotonin.bacnet4j.type.constructed.BaseType; 32 | 33 | abstract public class AbstractNotificationParameter extends BaseType { 34 | // Placeholder base class 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/primitive/Null.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.primitive; 30 | 31 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 32 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 33 | 34 | public class Null extends Primitive { 35 | public static final Null instance = new Null(); 36 | 37 | public static final byte TYPE_ID = 0; 38 | 39 | public Null() { 40 | // no op 41 | } 42 | 43 | public Null(final ByteQueue queue) throws BACnetErrorException { 44 | readTag(queue, TYPE_ID); 45 | } 46 | 47 | @Override 48 | public void writeImpl(final ByteQueue queue) { 49 | // no op 50 | } 51 | 52 | @Override 53 | protected long getLength() { 54 | return 0; 55 | } 56 | 57 | @Override 58 | public byte getTypeId() { 59 | return TYPE_ID; 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return 0; 65 | } 66 | 67 | @Override 68 | public boolean equals(final Object obj) { 69 | if (this == obj) 70 | return true; 71 | if (obj == null) 72 | return false; 73 | if (getClass() != obj.getClass()) 74 | return false; 75 | return true; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "Null"; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/primitive/Unsigned16.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.primitive; 30 | 31 | import java.math.BigInteger; 32 | 33 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 34 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 35 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 36 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 37 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 38 | 39 | public class Unsigned16 extends UnsignedInteger { 40 | private static final int MAX = 0xffff; 41 | private static final BigInteger BIGMAX = BigInteger.valueOf(MAX); 42 | 43 | public Unsigned16(final int value) { 44 | super(value); 45 | if (value > MAX) 46 | throw new IllegalArgumentException("Value cannot be greater than " + MAX); 47 | } 48 | 49 | public Unsigned16(final ByteQueue queue) throws BACnetErrorException { 50 | super(queue); 51 | } 52 | 53 | @Override 54 | public void validate() throws BACnetServiceException { 55 | super.validate(); 56 | if (super.isSmallValue()) { 57 | if (super.intValue() > MAX) { 58 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 59 | } 60 | } else { 61 | if (super.bigIntegerValue().compareTo(BIGMAX) > 0) { 62 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/primitive/Unsigned32.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.primitive; 30 | 31 | import java.math.BigInteger; 32 | 33 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 34 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 35 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 36 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 37 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 38 | 39 | public class Unsigned32 extends UnsignedInteger { 40 | private static final long MAX = 0xffffffffl; 41 | private static final BigInteger BIGMAX = BigInteger.valueOf(MAX); 42 | 43 | public Unsigned32(final int value) { 44 | super(value); 45 | } 46 | 47 | public Unsigned32(final BigInteger value) { 48 | super(value); 49 | if (value.longValue() > MAX) 50 | throw new IllegalArgumentException("Value cannot be greater than " + MAX); 51 | } 52 | 53 | public Unsigned32(final ByteQueue queue) throws BACnetErrorException { 54 | super(queue); 55 | } 56 | 57 | @Override 58 | public void validate() throws BACnetServiceException { 59 | super.validate(); 60 | if (super.isSmallValue()) { 61 | if (super.intValue() > MAX) { 62 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 63 | } 64 | } else { 65 | if (super.bigIntegerValue().compareTo(BIGMAX) > 0) { 66 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/type/primitive/Unsigned8.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.type.primitive; 30 | 31 | import java.math.BigInteger; 32 | 33 | import com.serotonin.bacnet4j.exception.BACnetErrorException; 34 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 35 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 36 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 37 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 38 | 39 | public class Unsigned8 extends UnsignedInteger { 40 | private static final int MAX = 0xff; 41 | private static final BigInteger BIGMAX = BigInteger.valueOf(MAX); 42 | 43 | public Unsigned8(final int value) { 44 | super(value); 45 | if (value > MAX) { 46 | throw new IllegalArgumentException("Value cannot be greater than " + MAX); 47 | } 48 | } 49 | 50 | public Unsigned8(final ByteQueue queue) throws BACnetErrorException { 51 | super(queue); 52 | } 53 | 54 | @Override 55 | public void validate() throws BACnetServiceException { 56 | super.validate(); 57 | if (super.isSmallValue()) { 58 | if (super.intValue() > MAX) { 59 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 60 | } 61 | } else { 62 | if (super.bigIntegerValue().compareTo(BIGMAX) > 0) { 63 | throw new BACnetServiceException(ErrorClass.property, ErrorCode.valueOutOfRange); 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/ReadListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util; 30 | 31 | import com.serotonin.bacnet4j.type.Encodable; 32 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 33 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 34 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 35 | 36 | @FunctionalInterface 37 | public interface ReadListener { 38 | /** 39 | * Provides the current progress from 0 (which is a value that is never actually sent to the method) up to 1 40 | * (finished and will not called again) as well as an opportunity for the client to cancel the request. Other 41 | * parameters represent the property that was just received. 42 | * 43 | * @param progress 44 | * the current progress amount 45 | * @param deviceId 46 | * the id of the device from which the property was received 47 | * @param oid 48 | * the oid of the property that was received 49 | * @param pid 50 | * the property id of the property that was received 51 | * @param pin 52 | * the index of the property that was received 53 | * @param value 54 | * the value of the property that was received 55 | * @return true if the request should be cancelled. 56 | */ 57 | boolean progress(double progress, int deviceId, ObjectIdentifier oid, PropertyIdentifier pid, 58 | UnsignedInteger pin, Encodable value); 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/ReadListenerUpdater.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util; 30 | 31 | import java.util.concurrent.atomic.AtomicInteger; 32 | 33 | import com.serotonin.bacnet4j.type.Encodable; 34 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 35 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 36 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 37 | 38 | public class ReadListenerUpdater { 39 | private final ReadListener callback; 40 | private final PropertyValues propertyValues; 41 | private final int max; 42 | private final AtomicInteger current = new AtomicInteger(0); 43 | private boolean cancelled; 44 | 45 | public ReadListenerUpdater(final ReadListener callback, final PropertyValues propertyValues, final int max) { 46 | this.callback = callback; 47 | this.propertyValues = propertyValues; 48 | this.max = max; 49 | } 50 | 51 | public void increment(final int deviceId, final ObjectIdentifier oid, final PropertyIdentifier pid, 52 | final UnsignedInteger pin, final Encodable value) { 53 | final int cur = current.incrementAndGet(); 54 | if (callback != null) 55 | cancelled = callback.progress((double) cur / max, deviceId, oid, pid, pin, value); 56 | propertyValues.add(oid, pid, pin, value); 57 | } 58 | 59 | public boolean cancelled() { 60 | return cancelled; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/RemoteDeviceTimeoutCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util; 30 | 31 | @FunctionalInterface 32 | public interface RemoteDeviceTimeoutCallback { 33 | void remoteDeviceTimeout(); 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/sero/IpWhiteListException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util.sero; 30 | 31 | /** 32 | * @author Matthew Lohbihler 33 | */ 34 | public class IpWhiteListException extends Exception { 35 | private static final long serialVersionUID = -1; 36 | 37 | public IpWhiteListException(String message) { 38 | super(message); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/sero/LineHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util.sero; 30 | 31 | /** 32 | * @author Matthew Lohbihler 33 | */ 34 | public interface LineHandler { 35 | public void handleLine(String line); 36 | 37 | public void done(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/serotonin/bacnet4j/util/sero/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================ 3 | * GNU General Public License 4 | * ============================================================================ 5 | * 6 | * Copyright (C) 2015 Infinite Automation Software. All rights reserved. 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | * 20 | * When signing a commercial license with Infinite Automation Software, 21 | * the following extension to GPL is made. A special exception to the GPL is 22 | * included to allow you to distribute a combined work that includes BAcnet4J 23 | * without being obliged to provide the source code for any proprietary components. 24 | * 25 | * See www.infiniteautomation.com for commercial license options. 26 | * 27 | * @author Matthew Lohbihler 28 | */ 29 | package com.serotonin.bacnet4j.util.sero; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | public class Utils { 35 | public static byte[] commaSeparatedHex(final String s) { 36 | final String[] parts = s.split(","); 37 | final byte[] result = new byte[parts.length]; 38 | for (int i = 0; i < parts.length; i++) 39 | result[i] = (byte) Integer.parseInt(parts[i], 16); 40 | return result; 41 | } 42 | 43 | @SafeVarargs 44 | public static List toList(final T... elements) { 45 | final List list = new ArrayList<>(); 46 | for (final T e : elements) 47 | list.add(e); 48 | return list; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/SetupTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.junit.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.serotonin.bacnet4j.npdu.test.TestNetwork; 11 | import com.serotonin.bacnet4j.npdu.test.TestNetworkMap; 12 | import com.serotonin.bacnet4j.transport.DefaultTransport; 13 | 14 | import lohbihler.warp.WarpClock; 15 | 16 | public class SetupTest { 17 | static final Logger LOG = LoggerFactory.getLogger(SetupTest.class); 18 | 19 | private final int timeout = 200; 20 | 21 | @Test 22 | public void setup() throws Exception { 23 | final int count = 20; 24 | final TestNetworkMap map = new TestNetworkMap(); 25 | final WarpClock clock = new WarpClock(); 26 | 27 | final List lds = new ArrayList<>(); 28 | for (int i = 0; i < count; i++) { 29 | lds.add(new LocalDevice(i, new DefaultTransport(new TestNetwork(map, i, 0).withTimeout(timeout))) 30 | .withClock(clock)); 31 | } 32 | 33 | for (int i = 0; i < count; i++) { 34 | lds.get(i).initialize(); 35 | } 36 | 37 | for (int i = 0; i < count; i++) { 38 | final LocalDevice d = lds.get(i); 39 | for (int j = 0; j < count; j++) { 40 | if (i != j) { 41 | if ((i + j) % 2 == 0) { 42 | d.getRemoteDevice(j).get(); 43 | } else { 44 | d.getRemoteDeviceBlocking(j); 45 | } 46 | } 47 | } 48 | } 49 | 50 | for (int i = 0; i < count; i++) { 51 | lds.get(i).terminate(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/adhoc/BACnetIpUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Radix IoT LLC. All rights reserved. 3 | * @Author Terry Packer 4 | * 5 | */ 6 | 7 | package com.serotonin.bacnet4j.adhoc; 8 | 9 | import java.net.InterfaceAddress; 10 | import java.net.NetworkInterface; 11 | import java.net.SocketException; 12 | import java.util.ArrayList; 13 | import java.util.Enumeration; 14 | import java.util.List; 15 | 16 | /** 17 | * @author Terry Packer 18 | * 19 | */ 20 | public class BACnetIpUtils { 21 | 22 | private BACnetIpUtils() { } 23 | 24 | public static void main(final String[] args) throws Exception { 25 | List usable = listUsableBACnetInterfaces(); 26 | for(InterfaceAddress ifAddr : usable) { 27 | System.out.println("Address: " + ifAddr.getAddress()); 28 | System.out.println("Broadcast: " + ifAddr.getBroadcast()); 29 | } 30 | } 31 | 32 | /** 33 | * List all usable Interface addresses on the local machine. 34 | * 35 | * Usable: is not loopback, is up, has broadcast address 36 | * 37 | * @return 38 | * @throws SocketException 39 | */ 40 | public static List listUsableBACnetInterfaces() throws SocketException { 41 | List usable = new ArrayList<>(); 42 | Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); 43 | while (interfaces.hasMoreElements()) { 44 | NetworkInterface networkInterface = interfaces.nextElement(); 45 | 46 | if (networkInterface.isLoopback() || !networkInterface.isUp()) { 47 | continue; 48 | } 49 | for(InterfaceAddress add : networkInterface.getInterfaceAddresses()) { 50 | if(add.getBroadcast() != null) { 51 | usable.add(add); 52 | } 53 | 54 | } 55 | } 56 | return usable; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/adhoc/DateRangeTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.adhoc; 2 | 3 | import com.serotonin.bacnet4j.type.constructed.DateRange; 4 | import com.serotonin.bacnet4j.type.constructed.DateTime; 5 | import com.serotonin.bacnet4j.type.primitive.Date; 6 | 7 | public class DateRangeTest { 8 | public static void main(final String[] args) { 9 | final DateTime now = new DateTime(System.currentTimeMillis()); 10 | final DateRange dateRange = new DateRange(new Date(2017, null, Date.UNSPECIFIED_DAY, null), 11 | new Date(2019, null, Date.UNSPECIFIED_DAY, null)); 12 | System.out.println(dateRange.matches(now.getDate())); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/cache/RemoteEntityCacheTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.cache; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import org.junit.Test; 7 | 8 | import com.serotonin.bacnet4j.LocalDevice; 9 | import com.serotonin.bacnet4j.npdu.test.TestNetwork; 10 | import com.serotonin.bacnet4j.npdu.test.TestNetworkMap; 11 | import com.serotonin.bacnet4j.transport.DefaultTransport; 12 | 13 | import lohbihler.warp.WarpClock; 14 | 15 | public class RemoteEntityCacheTest { 16 | private final TestNetworkMap map = new TestNetworkMap(); 17 | 18 | @Test 19 | public void test() { 20 | final WarpClock clock = new WarpClock(); 21 | final LocalDevice d = new LocalDevice(0, new DefaultTransport(new TestNetwork(map, 1, 10))).withClock(clock); 22 | 23 | final RemoteEntityCache cache = new RemoteEntityCache<>(d); 24 | 25 | cache.putEntity("key1", "value1", RemoteEntityCachePolicy.NEVER_CACHE); 26 | cache.putEntity("key2", "value2", RemoteEntityCachePolicy.EXPIRE_5_SECONDS); 27 | cache.putEntity("key3", "value3", RemoteEntityCachePolicy.NEVER_EXPIRE); 28 | 29 | assertNull(cache.getCachedEntity("key1")); 30 | assertEquals("value2", cache.getCachedEntity("key2")); 31 | assertEquals("value3", cache.getCachedEntity("key3")); 32 | 33 | // Advance the clock 10 seconds 34 | clock.plusSeconds(10); 35 | 36 | assertNull(cache.getCachedEntity("key1")); 37 | assertNull(cache.getCachedEntity("key2")); 38 | assertEquals("value3", cache.getCachedEntity("key3")); 39 | 40 | // Advance the clock 1 year 41 | clock.plusYears(1); 42 | 43 | assertNull(cache.getCachedEntity("key1")); 44 | assertNull(cache.getCachedEntity("key2")); 45 | assertEquals("value3", cache.getCachedEntity("key3")); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/npdu/NPCITest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu; 2 | 3 | import static org.junit.Assert.assertArrayEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import com.serotonin.bacnet4j.npdu.NPCI.NetworkPriority; 8 | import com.serotonin.bacnet4j.type.constructed.Address; 9 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 10 | 11 | public class NPCITest { 12 | @Test 13 | public void priorityTest() { 14 | NPCI npci = new NPCI(new Address(2, new byte[] { 1 })); 15 | System.out.println(npci.getNetworkPriority()); 16 | npci.priority(NetworkPriority.criticalEquipment); 17 | System.out.println(npci.getNetworkPriority()); 18 | 19 | ByteQueue queue = new ByteQueue(); 20 | npci.write(queue); 21 | System.out.println(queue); 22 | 23 | byte[] expected = { 0x1, // version 24 | 0x2a, // control Bx00101010 25 | (byte) 0xff, (byte) 0xff, // dest all networks 26 | 0x0, // dest address length 27 | 0x0, 0x2, // source network 28 | 0x1, // source address length 29 | 0x1, // source address 30 | (byte) 0xff, // hop count 31 | }; 32 | assertArrayEquals(expected, queue.popAll()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/npdu/NetworkUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu; 2 | 3 | import org.junit.Test; 4 | 5 | public class NetworkUtilsTest { 6 | @Test 7 | public void ipV6() throws Exception { 8 | System.out.println(NetworkUtils.toOctetString("[::1]:456").getDescription()); 9 | System.out.println(NetworkUtils.toOctetString("192.168.0.123:47808").getDescription()); 10 | 11 | // 12 | // System.out.println(InetAddress.getByName("[::1]")); 13 | // System.out.println(InetAddress.getByName("::1")); 14 | // System.out.println(InetAddress.getByName("::1").toString()); 15 | // 16 | // URI uri = new URI("my://" + s); 17 | // System.out.println(uri.getHost()); 18 | // System.out.println(uri.getPort()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/npdu/ip/IpNetworkBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu.ip; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class IpNetworkBuilderTest { 8 | @Test 9 | public void withSubnet16() { 10 | final IpNetworkBuilder builder = new IpNetworkBuilder().withSubnet("192.168.0.0", 16); 11 | assertEquals("192.168.255.255", builder.getBroadcastAddress()); 12 | assertEquals("255.255.0.0", builder.getSubnetMask()); 13 | } 14 | 15 | @Test 16 | public void withBroadcast16() { 17 | final IpNetworkBuilder builder = new IpNetworkBuilder().withBroadcast("192.168.255.255", 16); 18 | assertEquals("192.168.255.255", builder.getBroadcastAddress()); 19 | assertEquals("255.255.0.0", builder.getSubnetMask()); 20 | } 21 | 22 | @Test 23 | public void withSubnet24() { 24 | final IpNetworkBuilder builder = new IpNetworkBuilder().withSubnet("192.168.2.0", 24); 25 | assertEquals("192.168.2.255", builder.getBroadcastAddress()); 26 | assertEquals("255.255.255.0", builder.getSubnetMask()); 27 | } 28 | 29 | @Test 30 | public void withBroadcast24() { 31 | final IpNetworkBuilder builder = new IpNetworkBuilder().withBroadcast("192.168.4.255", 24); 32 | assertEquals("192.168.4.255", builder.getBroadcastAddress()); 33 | assertEquals("255.255.255.0", builder.getSubnetMask()); 34 | } 35 | 36 | @Test 37 | public void withSubnet19() { 38 | final IpNetworkBuilder builder = new IpNetworkBuilder().withSubnet("192.168.192.0", 19); 39 | assertEquals("192.168.223.255", builder.getBroadcastAddress()); 40 | assertEquals("255.255.224.0", builder.getSubnetMask()); 41 | } 42 | 43 | @Test 44 | public void withBroadcast19() { 45 | final IpNetworkBuilder builder = new IpNetworkBuilder().withBroadcast("192.168.223.255", 19); 46 | assertEquals("192.168.223.255", builder.getBroadcastAddress()); 47 | assertEquals("255.255.224.0", builder.getSubnetMask()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/npdu/ip/IpNetworkUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.npdu.ip; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class IpNetworkUtilsTest { 8 | @Test 9 | public void createSubmask() { 10 | assertEquals(0x00000000L, IpNetworkUtils.createMask(0)); 11 | assertEquals(0x80000000L, IpNetworkUtils.createMask(1)); 12 | assertEquals(0xC0000000L, IpNetworkUtils.createMask(2)); 13 | assertEquals(0xE0000000L, IpNetworkUtils.createMask(3)); 14 | assertEquals(0xF0000000L, IpNetworkUtils.createMask(4)); 15 | assertEquals(0xF8000000L, IpNetworkUtils.createMask(5)); 16 | assertEquals(0xFC000000L, IpNetworkUtils.createMask(6)); 17 | assertEquals(0xFE000000L, IpNetworkUtils.createMask(7)); 18 | assertEquals(0xFF000000L, IpNetworkUtils.createMask(8)); 19 | assertEquals(0xFF800000L, IpNetworkUtils.createMask(9)); 20 | assertEquals(0xFFC00000L, IpNetworkUtils.createMask(10)); 21 | assertEquals(0xFFE00000L, IpNetworkUtils.createMask(11)); 22 | assertEquals(0xFFF00000L, IpNetworkUtils.createMask(12)); 23 | assertEquals(0xFFF80000L, IpNetworkUtils.createMask(13)); 24 | assertEquals(0xFFFC0000L, IpNetworkUtils.createMask(14)); 25 | assertEquals(0xFFFE0000L, IpNetworkUtils.createMask(15)); 26 | assertEquals(0xFFFF0000L, IpNetworkUtils.createMask(16)); 27 | assertEquals(0xFFFF8000L, IpNetworkUtils.createMask(17)); 28 | assertEquals(0xFFFFC000L, IpNetworkUtils.createMask(18)); 29 | assertEquals(0xFFFFE000L, IpNetworkUtils.createMask(19)); 30 | assertEquals(0xFFFFF000L, IpNetworkUtils.createMask(20)); 31 | assertEquals(0xFFFFF800L, IpNetworkUtils.createMask(21)); 32 | assertEquals(0xFFFFFC00L, IpNetworkUtils.createMask(22)); 33 | assertEquals(0xFFFFFE00L, IpNetworkUtils.createMask(23)); 34 | assertEquals(0xFFFFFF00L, IpNetworkUtils.createMask(24)); 35 | assertEquals(0xFFFFFF80L, IpNetworkUtils.createMask(25)); 36 | assertEquals(0xFFFFFFC0L, IpNetworkUtils.createMask(26)); 37 | assertEquals(0xFFFFFFE0L, IpNetworkUtils.createMask(27)); 38 | assertEquals(0xFFFFFFF0L, IpNetworkUtils.createMask(28)); 39 | assertEquals(0xFFFFFFF8L, IpNetworkUtils.createMask(29)); 40 | assertEquals(0xFFFFFFFCL, IpNetworkUtils.createMask(30)); 41 | assertEquals(0xFFFFFFFEL, IpNetworkUtils.createMask(31)); 42 | assertEquals(0xFFFFFFFFL, IpNetworkUtils.createMask(32)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/obj/CovNotifListener.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.serotonin.bacnet4j.event.DeviceEventAdapter; 12 | import com.serotonin.bacnet4j.type.constructed.PropertyValue; 13 | import com.serotonin.bacnet4j.type.constructed.SequenceOf; 14 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 15 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 16 | 17 | public class CovNotifListener extends DeviceEventAdapter { 18 | static final Logger LOG = LoggerFactory.getLogger(CovNotifListener.class); 19 | 20 | public final List> notifs = new ArrayList<>(); 21 | 22 | @Override 23 | public void covNotificationReceived(final UnsignedInteger subscriberProcessIdentifier, 24 | final ObjectIdentifier initiatingDevice, final ObjectIdentifier monitoredObjectIdentifier, 25 | final UnsignedInteger timeRemaining, final SequenceOf listOfValues) { 26 | LOG.info("COV notification received."); 27 | 28 | final Map notif = new HashMap<>(); 29 | notif.put("subscriberProcessIdentifier", subscriberProcessIdentifier); 30 | notif.put("initiatingDevice", initiatingDevice); 31 | notif.put("monitoredObjectIdentifier", monitoredObjectIdentifier); 32 | notif.put("timeRemaining", timeRemaining); 33 | notif.put("listOfValues", listOfValues); 34 | notifs.add(notif); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/obj/EventNotifListener.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.serotonin.bacnet4j.event.DeviceEventAdapter; 12 | import com.serotonin.bacnet4j.type.constructed.TimeStamp; 13 | import com.serotonin.bacnet4j.type.enumerated.EventState; 14 | import com.serotonin.bacnet4j.type.enumerated.EventType; 15 | import com.serotonin.bacnet4j.type.enumerated.NotifyType; 16 | import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters; 17 | import com.serotonin.bacnet4j.type.primitive.Boolean; 18 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 19 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 20 | import com.serotonin.bacnet4j.type.primitive.UnsignedInteger; 21 | 22 | public class EventNotifListener extends DeviceEventAdapter { 23 | static final Logger LOG = LoggerFactory.getLogger(EventNotifListener.class); 24 | 25 | public final List> notifs = new ArrayList<>(); 26 | 27 | @Override 28 | public void eventNotificationReceived(final UnsignedInteger processIdentifier, 29 | final ObjectIdentifier initiatingDevice, final ObjectIdentifier eventObjectIdentifier, 30 | final TimeStamp timeStamp, final UnsignedInteger notificationClass, final UnsignedInteger priority, 31 | final EventType eventType, final CharacterString messageText, final NotifyType notifyType, 32 | final Boolean ackRequired, final EventState fromState, final EventState toState, 33 | final NotificationParameters eventValues) { 34 | LOG.debug("Event notification received."); 35 | 36 | final Map notif = new HashMap<>(); 37 | notif.put("processIdentifier", processIdentifier); 38 | notif.put("initiatingDevice", initiatingDevice); 39 | notif.put("eventObjectIdentifier", eventObjectIdentifier); 40 | notif.put("timeStamp", timeStamp); 41 | notif.put("notificationClass", notificationClass); 42 | notif.put("priority", priority); 43 | notif.put("eventType", eventType); 44 | notif.put("messageText", messageText); 45 | notif.put("notifyType", notifyType); 46 | notif.put("ackRequired", ackRequired); 47 | notif.put("fromState", fromState); 48 | notif.put("toState", toState); 49 | notif.put("eventValues", eventValues); 50 | notifs.add(notif); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/obj/ObjectPropertiesTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.obj; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import org.junit.Test; 7 | 8 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 9 | import com.serotonin.bacnet4j.type.enumerated.Reliability; 10 | 11 | public class ObjectPropertiesTest { 12 | @Test 13 | public void propertyDefinition() { 14 | // Reliability only ever has a type of Reliability 15 | final PropertyTypeDefinition def = ObjectProperties.getPropertyTypeDefinition(PropertyIdentifier.reliability); 16 | assertEquals(Reliability.class, def.getClazz()); 17 | assertEquals(null, def.getInnerType()); 18 | assertEquals(PropertyIdentifier.reliability, def.getPropertyIdentifier()); 19 | 20 | // Present value takes on different values in different objects. 21 | assertNull(ObjectProperties.getPropertyTypeDefinition(PropertyIdentifier.presentValue)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/service/confirmed/DeleteObjectRequestTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.service.confirmed; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import com.serotonin.bacnet4j.LocalDevice; 8 | import com.serotonin.bacnet4j.TestUtils; 9 | import com.serotonin.bacnet4j.exception.BACnetServiceException; 10 | import com.serotonin.bacnet4j.npdu.test.TestNetwork; 11 | import com.serotonin.bacnet4j.npdu.test.TestNetworkMap; 12 | import com.serotonin.bacnet4j.npdu.test.TestNetworkUtils; 13 | import com.serotonin.bacnet4j.obj.BACnetObject; 14 | import com.serotonin.bacnet4j.transport.DefaultTransport; 15 | import com.serotonin.bacnet4j.type.constructed.Address; 16 | import com.serotonin.bacnet4j.type.enumerated.ErrorClass; 17 | import com.serotonin.bacnet4j.type.enumerated.ErrorCode; 18 | import com.serotonin.bacnet4j.type.enumerated.ObjectType; 19 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 20 | 21 | public class DeleteObjectRequestTest { 22 | private final TestNetworkMap map = new TestNetworkMap(); 23 | private final Address addr = TestNetworkUtils.toAddress(2); 24 | private LocalDevice localDevice; 25 | 26 | @Before 27 | public void before() throws Exception { 28 | localDevice = new LocalDevice(1, new DefaultTransport(new TestNetwork(map, 1, 0))).initialize(); 29 | } 30 | 31 | @After 32 | public void after() { 33 | localDevice.terminate(); 34 | } 35 | 36 | @Test // 15.4.1.3.1 37 | public void errorTypes() { 38 | // Ask for an object that doesn't exist. 39 | TestUtils.assertRequestHandleException( // 40 | () -> new DeleteObjectRequest(new ObjectIdentifier(ObjectType.accessDoor, 0)).handle(localDevice, addr), 41 | ErrorClass.object, ErrorCode.unknownObject); 42 | } 43 | 44 | @Test // 15.4.1.3.1 45 | public void moreErrorTypes() throws BACnetServiceException { 46 | // Ask for an object that isn't deletable 47 | final BACnetObject bo = new BACnetObject(localDevice, ObjectType.accessDoor, 0); 48 | localDevice.addObject(bo); 49 | 50 | TestUtils.assertRequestHandleException( // 51 | () -> new DeleteObjectRequest(bo.getId()).handle(localDevice, addr), ErrorClass.object, 52 | ErrorCode.objectDeletionNotPermitted); 53 | } 54 | 55 | @Test 56 | public void delete() throws Exception { 57 | // Ask for an object that isn't deletable 58 | final BACnetObject bo = new BACnetObject(localDevice, ObjectType.accessDoor, 0); 59 | localDevice.addObject(bo); 60 | bo.setDeletable(true); 61 | 62 | new DeleteObjectRequest(bo.getId()).handle(localDevice, addr); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/service/unconfirmed/AutoDiscoveryTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.service.unconfirmed; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import org.junit.Test; 7 | 8 | import com.serotonin.bacnet4j.LocalDevice; 9 | import com.serotonin.bacnet4j.RemoteDevice; 10 | import com.serotonin.bacnet4j.RemoteObject; 11 | import com.serotonin.bacnet4j.event.DeviceEventAdapter; 12 | import com.serotonin.bacnet4j.npdu.test.TestNetwork; 13 | import com.serotonin.bacnet4j.npdu.test.TestNetworkMap; 14 | import com.serotonin.bacnet4j.transport.DefaultTransport; 15 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 16 | import com.serotonin.bacnet4j.type.enumerated.Segmentation; 17 | 18 | public class AutoDiscoveryTest { 19 | /** 20 | * Test to ensure that when an IHave is received from an unknown device that a properly configured RemoteDevice 21 | * object gets cached. 22 | * 23 | * @throws Exception 24 | */ 25 | @Test 26 | public void iHaveToWhoIs() throws Exception { 27 | final TestNetworkMap map = new TestNetworkMap(); 28 | final LocalDevice d1 = new LocalDevice(1, new DefaultTransport(new TestNetwork(map, 1, 0))).initialize(); 29 | final LocalDevice d2 = new LocalDevice(2, new DefaultTransport(new TestNetwork(map, 2, 0))).initialize(); 30 | 31 | d1.getEventHandler().addListener(new DeviceEventAdapter() { 32 | @Override 33 | public void iHaveReceived(final RemoteDevice d, final RemoteObject o) { 34 | assertEquals(Segmentation.segmentedBoth, d.getDeviceProperty(PropertyIdentifier.segmentationSupported)); 35 | } 36 | }); 37 | 38 | // Send an IHave from d2 39 | d2.sendGlobalBroadcast(new IHaveRequest(d2.getId(), d2.getId(), d2.get(PropertyIdentifier.objectName))); 40 | 41 | // Wait while d1 receives the IHave, sends a WhoIs to d2, and then receives an IAm from d2 and creates 42 | // a remote device from the content. 43 | Thread.sleep(300); 44 | 45 | // Now check that d1 has the correct information on d2. 46 | final RemoteDevice rd2 = d1.getCachedRemoteDevice(2); 47 | assertNotNull(rd2); 48 | // Check a property that is not in the IHave, but is in the IAm 49 | assertEquals(Segmentation.segmentedBoth, rd2.getDeviceProperty(PropertyIdentifier.segmentationSupported)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/EncodedValueTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import com.serotonin.bacnet4j.type.constructed.DateTime; 8 | import com.serotonin.bacnet4j.type.primitive.Boolean; 9 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 10 | import com.serotonin.bacnet4j.type.primitive.Real; 11 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 12 | 13 | public class EncodedValueTest { 14 | @Test 15 | public void constructed() throws Exception { 16 | final EncodedValue original = new EncodedValue(new CharacterString("test"), Boolean.TRUE, 17 | new DateTime(1491329790372L)); 18 | 19 | ByteQueue queue = new ByteQueue(); 20 | original.write(queue, 4); 21 | 22 | final EncodedValue parsed = new EncodedValue(queue, 4); 23 | assertEquals(original, parsed); 24 | 25 | queue = new ByteQueue(parsed.getData()); 26 | assertEquals(new CharacterString("test"), new CharacterString(queue)); 27 | assertEquals(Boolean.TRUE, new Boolean(queue)); 28 | assertEquals(new DateTime(1491329790372L), new DateTime(queue)); 29 | } 30 | 31 | @Test 32 | public void contextual() throws Exception { 33 | ByteQueue queue = new ByteQueue(); 34 | new Real(3.14F).write(queue); 35 | new CharacterString("test").write(queue); 36 | new DateTime(1491329790372L).write(queue, 0); 37 | Boolean.TRUE.write(queue, 1); 38 | Boolean.FALSE.write(queue, 12); 39 | final EncodedValue original = new EncodedValue(queue.popAll()); 40 | 41 | original.write(queue, 17); 42 | 43 | final EncodedValue parsed = new EncodedValue(queue, 17); 44 | queue = new ByteQueue(parsed.getData()); 45 | 46 | assertEquals(new Real(3.14F), new Real(queue)); 47 | assertEquals(new CharacterString("test"), new CharacterString(queue)); 48 | assertEquals(new DateTime(1491329790372L), Encodable.read(queue, DateTime.class, 0)); 49 | assertEquals(Boolean.TRUE, Encodable.read(queue, Boolean.class, 1)); 50 | assertEquals(Boolean.FALSE, Encodable.read(queue, Boolean.class, 12)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/constructed/BACnetArrayTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.constructed; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import com.serotonin.bacnet4j.exception.BACnetRuntimeException; 9 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 10 | 11 | public class BACnetArrayTest { 12 | @Test 13 | public void arrayTest() { 14 | final BACnetArray arr = new BACnetArray<>(3, CharacterString.EMPTY); 15 | assertEquals(3, arr.getCount()); 16 | 17 | arr.setBase1(1, new CharacterString("A")); 18 | arr.setBase1(3, new CharacterString("C")); 19 | assertEquals(3, arr.getCount()); 20 | assertEquals(arr.getBase1(1), new CharacterString("A")); 21 | assertEquals(arr.getBase1(2), CharacterString.EMPTY); 22 | assertEquals(arr.getBase1(3), new CharacterString("C")); 23 | 24 | try { 25 | arr.remove(2); 26 | Assert.fail("Should have failed"); 27 | } catch (@SuppressWarnings("unused") final BACnetRuntimeException e) { 28 | // no op 29 | } 30 | 31 | try { 32 | arr.add(new CharacterString("D")); 33 | Assert.fail("Should have failed"); 34 | } catch (@SuppressWarnings("unused") final BACnetRuntimeException e) { 35 | // no op 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/constructed/NameValueTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.constructed; 2 | 3 | import org.junit.Test; 4 | 5 | import com.serotonin.bacnet4j.TestUtils; 6 | import com.serotonin.bacnet4j.type.primitive.CharacterString; 7 | import com.serotonin.bacnet4j.type.primitive.Date; 8 | import com.serotonin.bacnet4j.type.primitive.Null; 9 | import com.serotonin.bacnet4j.type.primitive.OctetString; 10 | import com.serotonin.bacnet4j.type.primitive.Time; 11 | 12 | public class NameValueTest { 13 | @Test 14 | public void characterString() { 15 | final NameValue nv = new NameValue("tagName", new CharacterString("tagValue")); 16 | TestUtils.assertEncoding(nv, "0d08007461674e616d6575090074616756616c7565"); 17 | } 18 | 19 | @Test 20 | public void octetString() { 21 | final NameValue nv = new NameValue("tagName", new OctetString(new byte[] { 0, 1, 2, 3, 4, 5 })); 22 | TestUtils.assertEncoding(nv, "0d08007461674e616d656506000102030405"); 23 | } 24 | 25 | @Test 26 | public void dateTime() { 27 | final NameValue nv = new NameValue("tagName", DateTime.UNSPECIFIED); 28 | TestUtils.assertEncoding(nv, "0d08007461674e616d65a4ffffffffb4ffffffff"); 29 | } 30 | 31 | @Test 32 | public void optional() { 33 | final NameValue nv = new NameValue("tagName"); 34 | TestUtils.assertEncoding(nv, "0d08007461674e616d65"); 35 | } 36 | 37 | @Test 38 | public void sequence() { 39 | final SequenceOf seq = new SequenceOf<>( // 40 | new NameValue("t1", CharacterString.EMPTY), // 41 | new NameValue("t2"), // 42 | new NameValue("t3", new CharacterString("v1")), // 43 | new NameValue("t4", DateTime.UNSPECIFIED), // 44 | new NameValue("t6", Date.UNSPECIFIED), // 45 | new NameValue("t7", Time.UNSPECIFIED), // 46 | new NameValue("t5", Null.instance)); 47 | TestUtils.assertSequenceEncoding(seq, NameValue.class, 48 | "0b00743171000b0074320b007433730076310b007434a4ffffffffb4ffffffff0b007436a4ffffffff0b007437b4ffffffff0b00743500"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/constructed/ReadAccessResultTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.constructed; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import com.serotonin.bacnet4j.exception.BACnetException; 8 | import com.serotonin.bacnet4j.type.enumerated.ObjectType; 9 | import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier; 10 | import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier; 11 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 12 | 13 | public class ReadAccessResultTest { 14 | @Test 15 | public void decoding() throws BACnetException { 16 | final String hex = "0c020000021e294c4ec402000002c4008000004f1f"; 17 | 18 | final ReadAccessResult rar = new ReadAccessResult(new ByteQueue(hex)); 19 | 20 | assertEquals(ObjectType.device, rar.getObjectIdentifier().getObjectType()); 21 | assertEquals(2, rar.getObjectIdentifier().getInstanceNumber()); 22 | assertEquals(1, rar.getListOfResults().getCount()); 23 | assertEquals(PropertyIdentifier.objectList, rar.getListOfResults().getBase1(1).getPropertyIdentifier()); 24 | assertEquals(null, rar.getListOfResults().getBase1(1).getPropertyArrayIndex()); 25 | assertEquals(true, rar.getListOfResults().getBase1(1).getReadResult().isa(SequenceOf.class)); 26 | 27 | final SequenceOf oids = rar.getListOfResults().getBase1(1).getReadResult().getDatum(); 28 | assertEquals(2, oids.getCount()); 29 | assertEquals(new ObjectIdentifier(ObjectType.device, 2), oids.getBase1(1)); 30 | assertEquals(new ObjectIdentifier(ObjectType.analogValue, 0), oids.getBase1(2)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/primitive/RealTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.primitive; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import com.serotonin.bacnet4j.exception.BACnetException; 8 | import com.serotonin.bacnet4j.type.Encodable; 9 | import com.serotonin.bacnet4j.util.sero.ByteQueue; 10 | 11 | public class RealTest { 12 | @Test 13 | public void nan() throws BACnetException { 14 | final Real r = new Real(Float.NaN); 15 | final ByteQueue queue = new ByteQueue(); 16 | r.write(queue); 17 | 18 | final Real r2 = Encodable.read(queue, Real.class); 19 | assertEquals(Float.NaN, r2.floatValue(), 0); 20 | } 21 | 22 | @Test 23 | public void neginf() throws BACnetException { 24 | final Real r = new Real(Float.NEGATIVE_INFINITY); 25 | final ByteQueue queue = new ByteQueue(); 26 | r.write(queue); 27 | 28 | final Real r2 = Encodable.read(queue, Real.class); 29 | assertEquals(Float.NEGATIVE_INFINITY, r2.floatValue(), 0); 30 | } 31 | 32 | @Test 33 | public void posinf() throws BACnetException { 34 | final Real r = new Real(Float.POSITIVE_INFINITY); 35 | final ByteQueue queue = new ByteQueue(); 36 | r.write(queue); 37 | 38 | final Real r2 = Encodable.read(queue, Real.class); 39 | assertEquals(Float.POSITIVE_INFINITY, r2.floatValue(), 0); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/primitive/TimeTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.primitive; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import org.junit.Test; 8 | 9 | public class TimeTest { 10 | @Test 11 | public void comparison() { 12 | assertFalse(new Time(12, 1, 1, 1).before(new Time(11, 2, 2, 2))); 13 | assertFalse(new Time(12, 1, 1, 1).before(new Time(12, 0, 2, 2))); 14 | assertFalse(new Time(12, 1, 1, 1).before(new Time(12, 1, 0, 2))); 15 | assertFalse(new Time(12, 1, 1, 1).before(new Time(12, 1, 1, 1))); 16 | assertTrue(new Time(12, 1, 1, 1).before(new Time(12, 1, 1, 2))); 17 | assertTrue(new Time(12, 1, 1, 1).before(new Time(12, 1, 2, 0))); 18 | assertTrue(new Time(12, 1, 1, 1).before(new Time(12, 2, 0, 0))); 19 | assertTrue(new Time(12, 1, 1, 1).before(new Time(13, 0, 0, 0))); 20 | } 21 | 22 | @Test 23 | public void diff() { 24 | assertEquals(1, new Time(1, 1, 1, 1).getSmallestDiff(new Time(1, 1, 1, 0))); 25 | assertEquals(1, new Time(1, 1, 1, 0).getSmallestDiff(new Time(1, 1, 1, 1))); 26 | assertEquals(240_000, new Time(23, 30, 0, 0).getSmallestDiff(new Time(0, 10, 0, 0))); 27 | assertEquals(240_000, new Time(0, 10, 0, 0).getSmallestDiff(new Time(23, 30, 0, 0))); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/type/primitive/UnsignedIntegerTest.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.type.primitive; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class UnsignedIntegerTest { 8 | @Test 9 | public void increment32() { 10 | UnsignedInteger i = new UnsignedInteger(0xFFFFFFFDL); 11 | assertEquals(0xFFFFFFFDL, i.longValue()); 12 | 13 | i = i.increment32(); 14 | assertEquals(0xFFFFFFFEL, i.longValue()); 15 | 16 | i = i.increment32(); 17 | assertEquals(0xFFFFFFFFL, i.longValue()); 18 | 19 | i = i.increment32(); 20 | assertEquals(0, i.longValue()); 21 | 22 | i = i.increment32(); 23 | assertEquals(1, i.longValue()); 24 | } 25 | 26 | @Test 27 | public void increment16() { 28 | UnsignedInteger i = new UnsignedInteger(65533); 29 | assertEquals(65533, i.intValue()); 30 | 31 | i = i.increment16(); 32 | assertEquals(65534, i.intValue()); 33 | 34 | i = i.increment16(); 35 | assertEquals(65535, i.intValue()); 36 | 37 | i = i.increment16(); 38 | assertEquals(0, i.intValue()); 39 | 40 | i = i.increment16(); 41 | assertEquals(1, i.intValue()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/util/JsscSerialPortInputStream.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.util; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import com.serotonin.bacnet4j.util.sero.ThreadUtils; 7 | 8 | import jssc.SerialPort; 9 | import jssc.SerialPortException; 10 | 11 | public class JsscSerialPortInputStream extends InputStream { 12 | private final SerialPort serialPort; 13 | 14 | public JsscSerialPortInputStream(final SerialPort serialPort) { 15 | this.serialPort = serialPort; 16 | } 17 | 18 | @Override 19 | public int read() throws IOException { 20 | try { 21 | while (true) { 22 | final byte[] b = serialPort.readBytes(1); 23 | if (b == null) { 24 | ThreadUtils.sleep(20); 25 | continue; 26 | } 27 | return b[0]; 28 | } 29 | } catch (final SerialPortException e) { 30 | throw new IOException(e); 31 | } 32 | } 33 | 34 | @Override 35 | public int read(final byte[] b, final int off, final int len) throws IOException { 36 | if (len == 0) { 37 | return 0; 38 | } 39 | 40 | try { 41 | int length = serialPort.getInputBufferBytesCount(); 42 | if (length > len) { 43 | length = len; 44 | } 45 | 46 | final byte[] buf = serialPort.readBytes(length); 47 | System.arraycopy(buf, 0, b, off, length); 48 | return length; 49 | } catch (final SerialPortException e) { 50 | throw new IOException(e); 51 | } 52 | } 53 | 54 | @Override 55 | public int available() throws IOException { 56 | try { 57 | return serialPort.getInputBufferBytesCount(); 58 | } catch (final SerialPortException e) { 59 | throw new IOException(e); 60 | } 61 | } 62 | 63 | // @Override 64 | // public void close() throws IOException { 65 | // // TODO Auto-generated method stub 66 | // super.close(); 67 | // } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/com/serotonin/bacnet4j/util/JsscSerialPortOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.serotonin.bacnet4j.util; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import jssc.SerialPort; 7 | import jssc.SerialPortException; 8 | 9 | public class JsscSerialPortOutputStream extends OutputStream { 10 | private final SerialPort serialPort; 11 | 12 | public JsscSerialPortOutputStream(final SerialPort serialPort) { 13 | this.serialPort = serialPort; 14 | } 15 | 16 | @Override 17 | public void write(final int b) throws IOException { 18 | try { 19 | serialPort.writeByte((byte) b); 20 | } catch (final SerialPortException e) { 21 | throw new IOException(e); 22 | } 23 | } 24 | 25 | @Override 26 | public void write(final byte[] b) throws IOException { 27 | try { 28 | serialPort.writeBytes(b); 29 | } catch (final SerialPortException e) { 30 | throw new IOException(e); 31 | } 32 | } 33 | 34 | // @Override 35 | // public void close() throws IOException { 36 | // // TODO Auto-generated method stub 37 | // super.close(); 38 | // } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/resources/backupTest.txt: -------------------------------------------------------------------------------- 1 | property.0=property 0 value 2 | property.1=property 1 value 3 | property.2=property 2 value 4 | property.3=property 3 value 5 | property.4=property 4 value 6 | property.5=property 5 value 7 | property.6=property 6 value 8 | property.7=property 7 value 9 | property.8=property 8 value 10 | property.9=property 9 value 11 | property.10=property 10 value 12 | property.11=property 11 value 13 | property.12=property 12 value 14 | property.13=property 13 value 15 | property.14=property 14 value 16 | property.15=property 15 value 17 | property.16=property 16 value 18 | property.17=property 17 value 19 | property.18=property 18 value 20 | property.19=property 19 value 21 | property.20=property 20 value 22 | property.21=property 21 value 23 | property.22=property 22 value 24 | property.23=property 23 value 25 | property.24=property 24 value 26 | property.25=property 25 value 27 | property.26=property 26 value 28 | property.27=property 27 value 29 | property.28=property 28 value 30 | property.29=property 29 value 31 | property.30=property 30 value 32 | property.31=property 31 value 33 | property.32=property 32 value 34 | property.33=property 33 value 35 | property.34=property 34 value 36 | property.35=property 35 value 37 | property.36=property 36 value 38 | property.37=property 37 value 39 | property.38=property 38 value 40 | property.39=property 39 value 41 | -------------------------------------------------------------------------------- /src/test/resources/fileObjectTest.txt: -------------------------------------------------------------------------------- 1 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 2 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzX 3 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzXX 4 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzX 5 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzXXXXXX 6 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 7 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 8 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzXX 9 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 10 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzXXXXXXXXXXXXX 11 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 12 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 13 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzX 14 | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 15 | -------------------------------------------------------------------------------- /src/test/resources/realtime-driver.properties: -------------------------------------------------------------------------------- 1 | # Dummy Properties for Driver 2 | N_MSTP=0x0 3 | MSTP_IOC_SETMACADDRESS=0x0 4 | MSTP_IOC_GETMACADDRESS=0x0 5 | F_SETFL=0x0 6 | O_NONBLOCK=0x0 7 | FNDELAY=0x0 8 | CLOCAL=0x0 9 | HUPCL=0x0 10 | CS8=0x0 11 | CSTOPB=0x0 12 | CREAD=0x0 13 | PARENB=0x0 14 | PARODD=0x0 15 | ICANON=0x0 16 | ECHO=0x0 17 | ECHOE=0x0 18 | ISIG=0x0 19 | IGNBRK=0x0 20 | IGNPAR=0x0 21 | VMIN=0x0 22 | VTIME=0x0 23 | TCIFLUSH=0x0 24 | TCSANOW=0x0 25 | ASYNC_LOW_LATENCY=0x0 26 | TIOCSETSD=0x0 27 | TIOCGSERIAL=0x0 28 | TIOCSSERIAL=0x0 29 | FIONREAD=0x0 -------------------------------------------------------------------------------- /src/test/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # Default logging detail level for all instances of SimpleLogger. 2 | # Must be one of ("trace", "debug", "info", "warn", or "error"). 3 | # If not specified, defaults to "info". 4 | org.slf4j.simpleLogger.defaultLogLevel=error 5 | 6 | # Set to true if you want the current date and time to be included in output messages. 7 | # Default is false, and will output the number of milliseconds elapsed since startup. 8 | org.slf4j.simpleLogger.showDateTime=true 9 | 10 | # The date and time format to be used in the output messages. 11 | # The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat. 12 | # If the format is not specified or is invalid, the default format is used. 13 | # The default format is yyyy-MM-dd HH:mm:ss:SSS Z. 14 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z 15 | 16 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.cache.RemoteDeviceCache=debug 17 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.BinaryOutputTest=debug 18 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.CommandableMixin=debug 19 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.mixin.IntrinsicReportingMixin=debug 20 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.mixin.ChangeOfStateMixin=debug 21 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.mixin.OutOfRangeMixin=debug 22 | #org.slf4j.simpleLogger.log.com.serotonin.bacnet4j.obj.mixin.FaultState=debug 23 | --------------------------------------------------------------------------------