• Recent
    • Tags
    • Popular
    • Register
    • Login
    1. Home
    2. robert bouwens

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website
    R
    • Profile
    • Following 0
    • Followers 0
    • Topics 12
    • Posts 36
    • Best 0
    • Controversial 0
    • Groups 0

    robert bouwens

    @robert bouwens

    0
    Reputation
    518
    Profile views
    36
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    robert bouwens Unfollow Follow

    Latest posts made by robert bouwens

    • RE: Bug in class AcknowledgementService

      the missing class:

      
      package com.serotonin.bacnet4j.service.acknowledgement;
      
      import com.serotonin.bacnet4j.exception.BACnetServiceException;
      import com.serotonin.util.queue.ByteQueue;
      
      public class DeleteObjectAck extends AcknowledgementService {
      	private static final long serialVersionUID = 3837098889443642131L;
      
      	public static final byte TYPE_ID = 11;
      
      	public DeleteObjectAck() {
      	}
      
      	@Override
      	public byte getChoiceId() {
      		return TYPE_ID;
      	}
      
      	@Override
      	public void write(ByteQueue queue) {
      	}
      
      	DeleteObjectAck(ByteQueue queue) throws BACnetServiceException {
      	}
      
      	@Override
      	public String toString() {
      		return "DeleteObjectAck()";
      	}
      
      	@Override
      	public int hashCode() {
      		final int PRIME = 31;
      		int result = 1;
      		result = PRIME * result;
      		return result;
      	}
      
      	@Override
      	public boolean equals(Object obj) {
      		if (this == obj)
      			return true;
      		if (obj == null)
      			return false;
      		if (getClass() != obj.getClass())
      			return false;
      		final DeleteObjectAck other = (DeleteObjectAck) obj;
      		if (this == other)
      			return true;
      		else
      			return false;
      	}
      }
      
      
      

      the result is not used anyway - if it fails the exception and the appr. error will be catched.

      posted in BACnet4J general discussion
      R
      robert bouwens
    • Bug in class AcknowledgementService

      we try to delete objects and found that the appropriate request is not handled at all.

      
      	        if (type == CreateObjectAck.TYPE_ID) // 10
      	            return new CreateObjectAck(queue);
      	        if (type == ReadPropertyAck.TYPE_ID) // 12
      	            return new ReadPropertyAck(queue);
      
      

      the service with type_id equal 11 is not coded!
      the missing code:

      
      	        if (type == DeleteObjectAck.TYPE_ID) // 11
      	            return new DeleteObjectAck(queue);
      
      

      and that new class is also not coded :)
      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • RE: Bug in class AcknowledgementService

      we try to delete objects and found that the appropriate request is not handled at all.

      
      	        if (type == CreateObjectAck.TYPE_ID) // 10
      	            return new CreateObjectAck(queue);
      	        if (type == ReadPropertyAck.TYPE_ID) // 12
      	            return new ReadPropertyAck(queue);
      
      

      the service with type_id equal 11 is not coded!
      the missing code:

      
      	        if (type == DeleteObjectAck.TYPE_ID) // 11
      	            return new DeleteObjectAck(queue);
      
      

      and that new class is also not coded :)
      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • Bug when sending segmented messages
              if (segmentsRequired > request.getMaxSegmentsAccepted() || segmentsRequired > 128)
                  throw new BACnetException("Response too big to send to device; too many segments required:" + segmentsRequired + ", accepted: " + request.getMaxSegmentsAccepted());
      

      above the code to determine the amount of acceptable segment messages.

      the implementation for getMaxSegmentsAccepted is wrong. it is defined as a bitmap.
      so we should change that piece of code to:

          public int getMaxSegmentsAccepted() {
          	switch (maxSegmentsAccepted)
          	{
          	case 0:
          		return 64;
          	case 1:
          		return 2;
          	case 2:
          		return 4;
          	case 3:
          		return 8;
          	case 4:
          		return 16;
          	case 5:
          		return 32;
          	case 6:
          		return 64;
          	case 7:
          		return 128;
          	
          	}
          	// 3 bits - we can't get here
              return 64;
          }
      
      

      this is in the class ConfirmedRequest.

      regards
      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • RE: Bug when sending segmented messages

      if (segmentsRequired > request.getMaxSegmentsAccepted() || segmentsRequired > 128)
      throw new BACnetException("Response too big to send to device; too many segments required:" + segmentsRequired + ", accepted: " + request.getMaxSegmentsAccepted());
      above the code to determine the amount of acceptable segment messages.

      the implementation for getMaxSegmentsAccepted is wrong. it is defined as a bitmap.
      so we should change that piece of code to:

          public int getMaxSegmentsAccepted() {
          	switch (maxSegmentsAccepted)
          	{
          	case 0:
          		return 64;
          	case 1:
          		return 2;
          	case 2:
          		return 4;
          	case 3:
          		return 8;
          	case 4:
          		return 16;
          	case 5:
          		return 32;
          	case 6:
          		return 64;
          	case 7:
          		return 128;
          	
          	}
          	// 3 bits - we can't get here
              return 64;
          }
      
      

      this is in the class ConfirmedRequest.

      regards
      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • ReadPropertyMultipleRequest

      when reading all properties from an object, then all properties defined will be returned.
      a bit too much.

          /**
           * add only defined/implemented properties.
           * 
           * @param obj
           * @param results
           * @param pid
           * @param pin
           */
      	private void addProperty(BACnetObject obj, List<Result> results,
      			PropertyIdentifier pid, UnsignedInteger pin) {
      		if (pid.intValue() == PropertyIdentifier.all.intValue()) {
                              // the properties implemented
      			List<PropertyIdentifier> properties = obj.getProperties();
      
      			for (PropertyIdentifier pd : properties) {
      				addProperty(obj, results, pd, pin);
      			}
      		} else if (pid.intValue() == PropertyIdentifier.required.intValue()) {
      			for (PropertyTypeDefinition def : ObjectProperties
      					.getRequiredPropertyTypeDefinitions(obj.getId()
      							.getObjectType()))
      				addProperty(obj, results, def.getPropertyIdentifier(), pin);
      		} else if (pid.intValue() == PropertyIdentifier.optional.intValue()) {
      			for (PropertyTypeDefinition def : ObjectProperties
      					.getOptionalPropertyTypeDefinitions(obj.getId()
      							.getObjectType()))
      				addProperty(obj, results, def.getPropertyIdentifier(), pin);
      		} else {
      			// Get the specified property.
      			try {
      				results.add(new Result(pid, pin, obj.getPropertyRequired(pid,
      						pin)));
      			} catch (BACnetServiceException e) {
      				results.add(new Result(pid, pin, new BACnetError(e
      						.getErrorClass(), e.getErrorCode())));
      			}
      		}
      	}
      
      

      in the class BACnetObject we add:

          /**
           * return all implemented properties
           * 
           * @return
           */
          public List<PropertyIdentifier> getProperties()
          {
          	ArrayList<PropertyIdentifier> list = new ArrayList<PropertyIdentifier>();
          	for ( PropertyIdentifier pid : properties.keySet())
          	{
          		list.add(pid);
          	}
          	return list;
          }
      
      

      with this modification only implemented and default properties will be taken into account.

      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • Statefull handling of the property services supported

      the stack is willing to answer every service request and this is bad ;-)
      at startup we defined the implemented services via the service supported property.
      un- and confirmed requests will be handled by the following corrections:

          /**
           * statefull handling of the property services supported
           * 
           * @param services
           * @param type
           * @param queue
           * @return
           * @throws BACnetException
           */
          public static UnconfirmedRequestService createUnconfirmedRequestService(ServicesSupported services, byte type, ByteQueue queue)
                  throws BACnetException {
              if (type == IAmRequest.TYPE_ID)
              {
              	if (services.isIAm())
              		return new IAmRequest(queue);
              	else
              		return null;
              }
              if (type == IHaveRequest.TYPE_ID)
              {
              	if (services.isIHave())
              		return new IHaveRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedCovNotificationRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedCovNotification())
              		return new UnconfirmedCovNotificationRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedEventNotificationRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedEventNotification())
              		return new UnconfirmedEventNotificationRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedPrivateTransferRequest.TYPE_ID)
              		if (services.isUnconfirmedPrivateTransfer())
              			return new UnconfirmedPrivateTransferRequest(queue);
              	else
              		return null;
              if (type == UnconfirmedTextMessageRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedTextMessage())
              		return new UnconfirmedTextMessageRequest(queue);
              	else
              		return null;
              }
              if (type == TimeSynchronizationRequest.TYPE_ID)
              {
              	if ( services.isTimeSynchronization())
              		return new TimeSynchronizationRequest(queue);
              	else
              		return null;
              }
              if (type == WhoHasRequest.TYPE_ID)
              {
              	if (services.isWhoHas())
                  return new WhoHasRequest(queue);
              	else
              		return null;
              }
              if (type == WhoIsRequest.TYPE_ID)
              {
              	if (services.isWhoIs())
              		return new WhoIsRequest(queue);
              	else
              		return null;
              }
              if (type == UTCTimeSynchronizationRequest.TYPE_ID)
              {
              	if (services.isUtcTimeSynchronization())
              		return new UTCTimeSynchronizationRequest(queue);
              	else
              		return null;
              }
      
              throw new BACnetException("Unsupported unconfirmed service: " + (type & 0xff));
          }
      
      

      we also need to mod the the class UnconfirmedRequest:

          public UnconfirmedRequest(ServicesSupported services, ByteQueue queue) throws BACnetException {
              queue.pop();
              byte choiceId = queue.pop();
              service = UnconfirmedRequestService.createUnconfirmedRequestService(services, choiceId, queue);
          }
      
      

      when the apdu will be created we need to take the upper mods into account and:

      abstract public class APDU {
          public static APDU createAPDU(ServicesSupported services, ByteQueue queue) throws BACnetException {
              // Get the first byte. The 4 high-order bits will tell us the type of PDU this is.
              byte type = queue.peek(0);
              type = (byte) ((type & 0xff) >> 4);
      
              if (type == ConfirmedRequest.TYPE_ID)
                  return new ConfirmedRequest(services, queue);
              if (type == UnconfirmedRequest.TYPE_ID)
                  return new UnconfirmedRequest(services, queue);
      
      

      unconfirmed request will not be answered when the service supported flag set to false.
      for confirmed service request it's a bit tricky.

          public static ConfirmedRequestService createConfirmedRequestService(ServicesSupported services, byte type, ByteQueue queue)
                  throws BACnetException {
              if (type == AcknowledgeAlarmRequest.TYPE_ID) // 0
              {
              	if (services.isAcknowledgeAlarm())
              		return new AcknowledgeAlarmRequest(queue);
              }
              else if (type == ConfirmedCovNotificationRequest.TYPE_ID) // 1
              {
              	if (services.isConfirmedCovNotification())
              		return new ConfirmedCovNotificationRequest(queue);
              }
              else if (type == ConfirmedEventNotificationRequest.TYPE_ID) // 2
              {
              	if (services.isConfirmedEventNotification())
              		return new ConfirmedEventNotificationRequest(queue);
              }
              else if (type == GetAlarmSummaryRequest.TYPE_ID) // 3
              {
              	if (services.isGetAlarmSummary())
              		return new GetAlarmSummaryRequest(queue);
              }
              else if (type == GetEnrollmentSummaryRequest.TYPE_ID) // 4
              {
              	if (services.isGetEnrollmentSummary())
              		return new GetEnrollmentSummaryRequest(queue);
              	else
              		throw new BACnetRejectException(RejectReason.unrecognizedService);
              }
              else if (type == SubscribeCOVRequest.TYPE_ID) // 5
              {
              	if (services.isConfirmedCovNotification())
              		return new SubscribeCOVRequest(queue);
              }
              else if (type == AtomicReadFileRequest.TYPE_ID) // 6
              {
              	if (services.isAtomicReadFile())
              		return new AtomicReadFileRequest(queue);
              }
              else if (type == AtomicWriteFileRequest.TYPE_ID) // 7
              {
              	if (services.isAtomicWriteFile())
              		return new AtomicWriteFileRequest(queue);
              }
              else if (type == AddListElementRequest.TYPE_ID) // 8
              {
              	if (services.isAddListElement())
              		return new AddListElementRequest(queue);
              } 
              else if (type == RemoveListElementRequest.TYPE_ID) // 9
              {
              	if (services.isRemoveListElement())
              		return new RemoveListElementRequest(queue);
              }
              else if (type == CreateObjectRequest.TYPE_ID) // 10
              {
              	if (services.isCreateObject())
              		return new CreateObjectRequest(queue);
              }
              else if (type == DeleteObjectRequest.TYPE_ID) // 11
              {
              	if (services.isDeleteObject())
              		return new DeleteObjectRequest(queue);
              }
              else if (type == ReadPropertyRequest.TYPE_ID) // 12
              {
                  return new ReadPropertyRequest(queue);
              }
              else if (type == ReadPropertyConditionalRequest.TYPE_ID) // 13
              {
              	if (services.isReadPropertyConditional())
              		return new ReadPropertyConditionalRequest(queue);
              }
              else if (type == ReadPropertyMultipleRequest.TYPE_ID) // 14
              {
              	if (services.isReadPropertyMultiple())
              		return new ReadPropertyMultipleRequest(queue);
              }
              else if (type == WritePropertyRequest.TYPE_ID) // 15
              {
              	if (services.isWritePropertyMultiple())
              		return new WritePropertyRequest(queue);
              }
              else if (type == WritePropertyMultipleRequest.TYPE_ID) // 16
              {
              	if (services.isWritePropertyMultiple())
              		return new WritePropertyMultipleRequest(queue);
              }
              else if (type == DeviceCommunicationControlRequest.TYPE_ID) // 17
              {
                 	if (services.isDeviceCommunicationControl())
                 		return new DeviceCommunicationControlRequest(queue);
              }
              else if (type == ConfirmedPrivateTransferRequest.TYPE_ID) // 18
              {
              	if (services.isConfirmedPrivateTransfer())
              		return new ConfirmedPrivateTransferRequest(queue);
              }
              else if (type == ConfirmedTextMessageRequest.TYPE_ID) // 19
              {
              	if (services.isConfirmedTextMessage())
              		return new ConfirmedTextMessageRequest(queue);
              }
              else if (type == ReinitializeDeviceRequest.TYPE_ID) // 20
              {
                 	if (services.isReinitializeDevice())
                 		return new ReinitializeDeviceRequest(queue);
              }
              else if (type == VtOpenRequest.TYPE_ID) // 21
              {
              	if (services.isVtOpen())
              		return new VtOpenRequest(queue);
              }
              else if (type == VtCloseRequest.TYPE_ID) // 22
              {
              	if (services.isVtClose())
              		return new VtCloseRequest(queue);
              }
              else if (type == VtDataRequest.TYPE_ID) // 23
              {
                 	if (services.isVtData())
                 		return new VtDataRequest(queue);
              }
              else if (type == AuthenticateRequest.TYPE_ID) // 24
              {
                 	if (services.isAuthenticate())
                 		return new AuthenticateRequest(queue);
              }
              else if (type == RequestKeyRequest.TYPE_ID) // 25
              {
              	if (services.isRequestKey())
              		return new RequestKeyRequest(queue);
              }
              else if (type == ReadRangeRequest.TYPE_ID) // 26
              {
              	if (services.isReadRange())
              		return new ReadRangeRequest(queue);
              }
              else if (type == LifeSafetyOperationRequest.TYPE_ID) // 27
              {
              	if (services.isLifeSafetyOperation())
                  return new LifeSafetyOperationRequest(queue);
              }
              else if (type == SubscribeCOVPropertyRequest.TYPE_ID) // 28
              {
              	if (services.isSubscribeCovProperty())
              		return new SubscribeCOVPropertyRequest(queue);
              }
              else if (type == GetEventInformation.TYPE_ID) // 29
              {
              	if (services.isGetEventInformation())
              		return new GetEventInformation(queue);
             }
      
              throw new BACnetErrorException(ErrorClass.device, ErrorCode.serviceRequestDenied);
          }
      
      

      the mods for the class, added membervariable services:

      public class ConfirmedRequest extends APDU implements Segmentable {
          public static final byte TYPE_ID = 0;
          private ServicesSupported services;
      ...
      

      in the class ipmessagecontrol we make shure it matches:

                  // Create the APDU.
                  try {
                  	ServicesSupported ss = (ServicesSupported) localDevice.getConfiguration().getProperty(PropertyIdentifier.protocolServicesSupported);
                      return APDU.createAPDU(ss, queue);
                  }
      
      

      and now i am open for discussions :)

      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • RE: ReadPropertyMultipleRequest

      when reading all properties from an object, then all properties defined will be returned.
      a bit too much.

          /**
           * add only defined/implemented properties.
           * 
           * @param obj
           * @param results
           * @param pid
           * @param pin
           */
      	private void addProperty(BACnetObject obj, List<Result> results,
      			PropertyIdentifier pid, UnsignedInteger pin) {
      		if (pid.intValue() == PropertyIdentifier.all.intValue()) {
                              // the properties implemented
      			List<PropertyIdentifier> properties = obj.getProperties();
      
      			for (PropertyIdentifier pd : properties) {
      				addProperty(obj, results, pd, pin);
      			}
      		} else if (pid.intValue() == PropertyIdentifier.required.intValue()) {
      			for (PropertyTypeDefinition def : ObjectProperties
      					.getRequiredPropertyTypeDefinitions(obj.getId()
      							.getObjectType()))
      				addProperty(obj, results, def.getPropertyIdentifier(), pin);
      		} else if (pid.intValue() == PropertyIdentifier.optional.intValue()) {
      			for (PropertyTypeDefinition def : ObjectProperties
      					.getOptionalPropertyTypeDefinitions(obj.getId()
      							.getObjectType()))
      				addProperty(obj, results, def.getPropertyIdentifier(), pin);
      		} else {
      			// Get the specified property.
      			try {
      				results.add(new Result(pid, pin, obj.getPropertyRequired(pid,
      						pin)));
      			} catch (BACnetServiceException e) {
      				results.add(new Result(pid, pin, new BACnetError(e
      						.getErrorClass(), e.getErrorCode())));
      			}
      		}
      	}
      
      

      in the class BACnetObject we add:

          /**
           * return all implemented properties
           * 
           * @return
           */
          public List<PropertyIdentifier> getProperties()
          {
          	ArrayList<PropertyIdentifier> list = new ArrayList<PropertyIdentifier>();
          	for ( PropertyIdentifier pid : properties.keySet())
          	{
          		list.add(pid);
          	}
          	return list;
          }
      
      

      with this modification only implemented and default properties will be taken into account.

      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • RE: Statefull handling of the property services supported

      the stack is willing to answer every service request and this is bad ;-)
      at startup we defined the implemented services via the service supported property.
      un- and confirmed requests will be handled by the following corrections:

          /**
           * statefull handling of the property services supported
           * 
           * @param services
           * @param type
           * @param queue
           * @return
           * @throws BACnetException
           */
          public static UnconfirmedRequestService createUnconfirmedRequestService(ServicesSupported services, byte type, ByteQueue queue)
                  throws BACnetException {
              if (type == IAmRequest.TYPE_ID)
              {
              	if (services.isIAm())
              		return new IAmRequest(queue);
              	else
              		return null;
              }
              if (type == IHaveRequest.TYPE_ID)
              {
              	if (services.isIHave())
              		return new IHaveRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedCovNotificationRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedCovNotification())
              		return new UnconfirmedCovNotificationRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedEventNotificationRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedEventNotification())
              		return new UnconfirmedEventNotificationRequest(queue);
              	else
              		return null;
              }
              if (type == UnconfirmedPrivateTransferRequest.TYPE_ID)
              		if (services.isUnconfirmedPrivateTransfer())
              			return new UnconfirmedPrivateTransferRequest(queue);
              	else
              		return null;
              if (type == UnconfirmedTextMessageRequest.TYPE_ID)
              {
              	if (services.isUnconfirmedTextMessage())
              		return new UnconfirmedTextMessageRequest(queue);
              	else
              		return null;
              }
              if (type == TimeSynchronizationRequest.TYPE_ID)
              {
              	if ( services.isTimeSynchronization())
              		return new TimeSynchronizationRequest(queue);
              	else
              		return null;
              }
              if (type == WhoHasRequest.TYPE_ID)
              {
              	if (services.isWhoHas())
                  return new WhoHasRequest(queue);
              	else
              		return null;
              }
              if (type == WhoIsRequest.TYPE_ID)
              {
              	if (services.isWhoIs())
              		return new WhoIsRequest(queue);
              	else
              		return null;
              }
              if (type == UTCTimeSynchronizationRequest.TYPE_ID)
              {
              	if (services.isUtcTimeSynchronization())
              		return new UTCTimeSynchronizationRequest(queue);
              	else
              		return null;
              }
      
              throw new BACnetException("Unsupported unconfirmed service: " + (type & 0xff));
          }
      
      

      we also need to mod the the class UnconfirmedRequest:

          public UnconfirmedRequest(ServicesSupported services, ByteQueue queue) throws BACnetException {
              queue.pop();
              byte choiceId = queue.pop();
              service = UnconfirmedRequestService.createUnconfirmedRequestService(services, choiceId, queue);
          }
      
      

      when the apdu will be created we need to take the upper mods into account and:

      abstract public class APDU {
          public static APDU createAPDU(ServicesSupported services, ByteQueue queue) throws BACnetException {
              // Get the first byte. The 4 high-order bits will tell us the type of PDU this is.
              byte type = queue.peek(0);
              type = (byte) ((type & 0xff) >> 4);
      
              if (type == ConfirmedRequest.TYPE_ID)
                  return new ConfirmedRequest(services, queue);
              if (type == UnconfirmedRequest.TYPE_ID)
                  return new UnconfirmedRequest(services, queue);
      
      

      unconfirmed request will not be answered when the service supported flag set to false.
      for confirmed service request it's a bit tricky.

          public static ConfirmedRequestService createConfirmedRequestService(ServicesSupported services, byte type, ByteQueue queue)
                  throws BACnetException {
              if (type == AcknowledgeAlarmRequest.TYPE_ID) // 0
              {
              	if (services.isAcknowledgeAlarm())
              		return new AcknowledgeAlarmRequest(queue);
              }
              else if (type == ConfirmedCovNotificationRequest.TYPE_ID) // 1
              {
              	if (services.isConfirmedCovNotification())
              		return new ConfirmedCovNotificationRequest(queue);
              }
              else if (type == ConfirmedEventNotificationRequest.TYPE_ID) // 2
              {
              	if (services.isConfirmedEventNotification())
              		return new ConfirmedEventNotificationRequest(queue);
              }
              else if (type == GetAlarmSummaryRequest.TYPE_ID) // 3
              {
              	if (services.isGetAlarmSummary())
              		return new GetAlarmSummaryRequest(queue);
              }
              else if (type == GetEnrollmentSummaryRequest.TYPE_ID) // 4
              {
              	if (services.isGetEnrollmentSummary())
              		return new GetEnrollmentSummaryRequest(queue);
              	else
              		throw new BACnetRejectException(RejectReason.unrecognizedService);
              }
              else if (type == SubscribeCOVRequest.TYPE_ID) // 5
              {
              	if (services.isConfirmedCovNotification())
              		return new SubscribeCOVRequest(queue);
              }
              else if (type == AtomicReadFileRequest.TYPE_ID) // 6
              {
              	if (services.isAtomicReadFile())
              		return new AtomicReadFileRequest(queue);
              }
              else if (type == AtomicWriteFileRequest.TYPE_ID) // 7
              {
              	if (services.isAtomicWriteFile())
              		return new AtomicWriteFileRequest(queue);
              }
              else if (type == AddListElementRequest.TYPE_ID) // 8
              {
              	if (services.isAddListElement())
              		return new AddListElementRequest(queue);
              } 
              else if (type == RemoveListElementRequest.TYPE_ID) // 9
              {
              	if (services.isRemoveListElement())
              		return new RemoveListElementRequest(queue);
              }
              else if (type == CreateObjectRequest.TYPE_ID) // 10
              {
              	if (services.isCreateObject())
              		return new CreateObjectRequest(queue);
              }
              else if (type == DeleteObjectRequest.TYPE_ID) // 11
              {
              	if (services.isDeleteObject())
              		return new DeleteObjectRequest(queue);
              }
              else if (type == ReadPropertyRequest.TYPE_ID) // 12
              {
                  return new ReadPropertyRequest(queue);
              }
              else if (type == ReadPropertyConditionalRequest.TYPE_ID) // 13
              {
              	if (services.isReadPropertyConditional())
              		return new ReadPropertyConditionalRequest(queue);
              }
              else if (type == ReadPropertyMultipleRequest.TYPE_ID) // 14
              {
              	if (services.isReadPropertyMultiple())
              		return new ReadPropertyMultipleRequest(queue);
              }
              else if (type == WritePropertyRequest.TYPE_ID) // 15
              {
              	if (services.isWritePropertyMultiple())
              		return new WritePropertyRequest(queue);
              }
              else if (type == WritePropertyMultipleRequest.TYPE_ID) // 16
              {
              	if (services.isWritePropertyMultiple())
              		return new WritePropertyMultipleRequest(queue);
              }
              else if (type == DeviceCommunicationControlRequest.TYPE_ID) // 17
              {
                 	if (services.isDeviceCommunicationControl())
                 		return new DeviceCommunicationControlRequest(queue);
              }
              else if (type == ConfirmedPrivateTransferRequest.TYPE_ID) // 18
              {
              	if (services.isConfirmedPrivateTransfer())
              		return new ConfirmedPrivateTransferRequest(queue);
              }
              else if (type == ConfirmedTextMessageRequest.TYPE_ID) // 19
              {
              	if (services.isConfirmedTextMessage())
              		return new ConfirmedTextMessageRequest(queue);
              }
              else if (type == ReinitializeDeviceRequest.TYPE_ID) // 20
              {
                 	if (services.isReinitializeDevice())
                 		return new ReinitializeDeviceRequest(queue);
              }
              else if (type == VtOpenRequest.TYPE_ID) // 21
              {
              	if (services.isVtOpen())
              		return new VtOpenRequest(queue);
              }
              else if (type == VtCloseRequest.TYPE_ID) // 22
              {
              	if (services.isVtClose())
              		return new VtCloseRequest(queue);
              }
              else if (type == VtDataRequest.TYPE_ID) // 23
              {
                 	if (services.isVtData())
                 		return new VtDataRequest(queue);
              }
              else if (type == AuthenticateRequest.TYPE_ID) // 24
              {
                 	if (services.isAuthenticate())
                 		return new AuthenticateRequest(queue);
              }
              else if (type == RequestKeyRequest.TYPE_ID) // 25
              {
              	if (services.isRequestKey())
              		return new RequestKeyRequest(queue);
              }
              else if (type == ReadRangeRequest.TYPE_ID) // 26
              {
              	if (services.isReadRange())
              		return new ReadRangeRequest(queue);
              }
              else if (type == LifeSafetyOperationRequest.TYPE_ID) // 27
              {
              	if (services.isLifeSafetyOperation())
                  return new LifeSafetyOperationRequest(queue);
              }
              else if (type == SubscribeCOVPropertyRequest.TYPE_ID) // 28
              {
              	if (services.isSubscribeCovProperty())
              		return new SubscribeCOVPropertyRequest(queue);
              }
              else if (type == GetEventInformation.TYPE_ID) // 29
              {
              	if (services.isGetEventInformation())
              		return new GetEventInformation(queue);
             }
      
              throw new BACnetErrorException(ErrorClass.device, ErrorCode.serviceRequestDenied);
          }
      
      

      the mods for the class, added membervariable services:

      public class ConfirmedRequest extends APDU implements Segmentable {
          public static final byte TYPE_ID = 0;
          private ServicesSupported services;
      ...
      

      in the class ipmessagecontrol we make shure it matches:

                  // Create the APDU.
                  try {
                  	ServicesSupported ss = (ServicesSupported) localDevice.getConfiguration().getProperty(PropertyIdentifier.protocolServicesSupported);
                      return APDU.createAPDU(ss, queue);
                  }
      
      

      and now i am open for discussions :)

      robert

      posted in BACnet4J general discussion
      R
      robert bouwens
    • RE: A small bug in the atomicwritefilerequest

      hello matt,

      a zero length file should be readable without error.
      and the standard says explicitly when the file size exceeds.

      if (start < 0 || start > file.length()

      is correct when reading the spec.
      and another commercial stack shows the same behaviour with the upper mod.

      regards
      robert

      posted in BACnet4J general discussion
      R
      robert bouwens