Example #1
0
        private void SendComplexAck(BacnetAddress adr, byte invoke_id, Segmentation segmentation, BacnetConfirmedServices service, Action<EncodeBuffer> apdu_content_encode)
        {
            Trace.WriteLine("Sending " + System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(service.ToString().ToLower()) + " ... ", null);

            //encode
            EncodeBuffer buffer;
            if (EncodeSegment(adr, invoke_id, segmentation, service, out buffer, apdu_content_encode))
            {
                //client doesn't support segments
                if (segmentation == null)
                {
                    Trace.TraceInformation("Segmenation denied");
                    ErrorResponse(adr, service, invoke_id, BacnetErrorClasses.ERROR_CLASS_SERVICES, BacnetErrorCodes.ERROR_CODE_ABORT_APDU_TOO_LONG);
                    buffer.result = EncodeResult.Good;     //don't continue the segmentation
                    return;
                }

                //first segment? validate max segments
                if (segmentation.sequence_number == 0)  //only validate first segment
                {
                    if (segmentation.max_segments != 0xFF && segmentation.buffer.offset > (segmentation.max_segments * (GetMaxApdu() - 5)))      //5 is adpu header
                    {
                        Trace.TraceInformation("Too much segmenation");
                        ErrorResponse(adr, service, invoke_id, BacnetErrorClasses.ERROR_CLASS_SERVICES, BacnetErrorCodes.ERROR_CODE_ABORT_APDU_TOO_LONG);
                        buffer.result = EncodeResult.Good;     //don't continue the segmentation
                        return;
                    }
                    else
                        Trace.WriteLine("Segmentation required", null);
                }

                //increment before ack can do so (race condition)
                unchecked { segmentation.sequence_number++; };
            }

            //send
            m_client.Send(buffer.buffer, m_client.HeaderLength, buffer.GetLength() - m_client.HeaderLength, adr, false, 0);
        }
Example #2
0
        protected void ProcessConfirmedServiceRequest(BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, BacnetMaxSegments max_segments, BacnetMaxAdpu max_adpu, byte invoke_id, byte[] buffer, int offset, int length)
        {
            try
            {
                Trace.WriteLine("ConfirmedServiceRequest", null);

                raw_buffer = buffer;
                raw_length = length;
                raw_offset = offset;

                if (OnConfirmedServiceRequest != null)
                    OnConfirmedServiceRequest(this, adr, type, service, max_segments, max_adpu, invoke_id, buffer, offset, length);

                //don't send segmented messages, if client don't want it
                if ((type & BacnetPduTypes.SEGMENTED_RESPONSE_ACCEPTED) == 0)
                    max_segments = BacnetMaxSegments.MAX_SEG0;

                if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY && OnReadPropertyRequest != null)
                {
                    BacnetObjectId object_id;
                    BacnetPropertyReference property;
                    if (Services.DecodeReadProperty(buffer, offset, length, out object_id, out property) >= 0)
                        OnReadPropertyRequest(this, adr, invoke_id, object_id, property, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode DecodeReadProperty");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY && OnWritePropertyRequest != null)
                {
                    BacnetObjectId object_id;
                    BacnetPropertyValue value;
                    if (Services.DecodeWriteProperty(buffer, offset, length, out object_id, out value) >= 0)
                        OnWritePropertyRequest(this, adr, invoke_id, object_id, value, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode DecodeWriteProperty");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROP_MULTIPLE && OnReadPropertyMultipleRequest != null)
                {
                    IList<BacnetReadAccessSpecification> properties;
                    if (Services.DecodeReadPropertyMultiple(buffer, offset, length, out properties) >= 0)
                        OnReadPropertyMultipleRequest(this, adr, invoke_id, properties, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode DecodeReadPropertyMultiple");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE && OnWritePropertyMultipleRequest != null)
                {
                    BacnetObjectId object_id;
                    ICollection<BacnetPropertyValue> values;
                    if (Services.DecodeWritePropertyMultiple(buffer, offset, length, out object_id, out values) >= 0)
                        OnWritePropertyMultipleRequest(this, adr, invoke_id, object_id, values, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode DecodeWritePropertyMultiple");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_COV_NOTIFICATION && OnCOVNotification != null)
                {
                    uint subscriberProcessIdentifier;
                    BacnetObjectId initiatingDeviceIdentifier;
                    BacnetObjectId monitoredObjectIdentifier;
                    uint timeRemaining;
                    ICollection<BacnetPropertyValue> values;
                    if (Services.DecodeCOVNotifyUnconfirmed(buffer, offset, length, out subscriberProcessIdentifier, out initiatingDeviceIdentifier, out monitoredObjectIdentifier, out timeRemaining, out values) >= 0)
                        OnCOVNotification(this, adr, invoke_id, subscriberProcessIdentifier, initiatingDeviceIdentifier, monitoredObjectIdentifier, timeRemaining, true, values, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode COVNotify");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE && OnAtomicWriteFileRequest != null)
                {
                    bool is_stream;
                    BacnetObjectId object_id;
                    int position;
                    uint block_count;
                    byte[][] blocks;
                    int[] counts;
                    if (Services.DecodeAtomicWriteFile(buffer, offset, length, out is_stream, out object_id, out position, out block_count, out blocks, out counts) >= 0)
                        OnAtomicWriteFileRequest(this, adr, invoke_id, is_stream, object_id, position, block_count, blocks, counts, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode AtomicWriteFile");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE && OnAtomicReadFileRequest != null)
                {
                    bool is_stream;
                    BacnetObjectId object_id;
                    int position;
                    uint count;
                    if (Services.DecodeAtomicReadFile(buffer, offset, length, out is_stream, out object_id, out position, out count) >= 0)
                        OnAtomicReadFileRequest(this, adr, invoke_id, is_stream, object_id, position, count, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode AtomicReadFile");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV && OnSubscribeCOV != null)
                {
                    uint subscriberProcessIdentifier;
                    BacnetObjectId monitoredObjectIdentifier;
                    bool cancellationRequest;
                    bool issueConfirmedNotifications;
                    uint lifetime;
                    if (Services.DecodeSubscribeCOV(buffer, offset, length, out subscriberProcessIdentifier, out monitoredObjectIdentifier, out cancellationRequest, out issueConfirmedNotifications, out lifetime) >= 0)
                        OnSubscribeCOV(this, adr, invoke_id, subscriberProcessIdentifier, monitoredObjectIdentifier, cancellationRequest, issueConfirmedNotifications, lifetime, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode SubscribeCOV");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY && OnSubscribeCOVProperty != null)
                {
                    uint subscriberProcessIdentifier;
                    BacnetObjectId monitoredObjectIdentifier;
                    BacnetPropertyReference monitoredProperty;
                    bool cancellationRequest;
                    bool issueConfirmedNotifications;
                    uint lifetime;
                    float covIncrement;
                    if (Services.DecodeSubscribeProperty(buffer, offset, length, out subscriberProcessIdentifier, out monitoredObjectIdentifier, out monitoredProperty, out cancellationRequest, out issueConfirmedNotifications, out lifetime, out covIncrement) >= 0)
                        OnSubscribeCOVProperty(this, adr, invoke_id, subscriberProcessIdentifier, monitoredObjectIdentifier, monitoredProperty, cancellationRequest, issueConfirmedNotifications, lifetime, covIncrement, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode SubscribeCOVProperty");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL && OnDeviceCommunicationControl != null)
                {
                    uint timeDuration;
                    uint enable_disable;
                    string password;
                    if (Services.DecodeDeviceCommunicationControl(buffer, offset, length, out timeDuration, out enable_disable, out password) >= 0)
                        OnDeviceCommunicationControl(this, adr, invoke_id, timeDuration, enable_disable, password, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode DeviceCommunicationControl");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_REINITIALIZE_DEVICE && OnReinitializedDevice != null)
                {
                    BacnetReinitializedStates state;
                    string password;
                    if (Services.DecodeReinitializeDevice(buffer, offset, length, out state, out password) >= 0)
                        OnReinitializedDevice(this, adr, invoke_id, state, password, max_segments);
                    else
                        Trace.TraceWarning("Couldn't decode ReinitializeDevice");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_EVENT_NOTIFICATION && OnEventNotify != null) // F. Chaxel
                {
                    BacnetEventNotificationData EventData;
                    if (Services.DecodeEventNotifyData(buffer, offset, length, out EventData) >= 0)
                    {
                        OnEventNotify(this, adr, EventData);
                    }
                    else
                        Trace.TraceWarning("Couldn't decode Event/Alarm Notification");
                }
                else if (service == BacnetConfirmedServices.SERVICE_CONFIRMED_READ_RANGE && OnReadRange != null)
                {
                    BacnetObjectId objectId;
                    BacnetPropertyReference property;
                    BacnetReadRangeRequestTypes requestType;
                    uint position;
                    DateTime time;
                    int count;
                    if (Services.DecodeReadRange(buffer, offset, length, out objectId, out property, out requestType, out position, out time, out count) >= 0)
                    {
                        OnReadRange(this, adr, invoke_id, objectId, property, requestType, position, time, count, max_segments);
                    }
                    else
                        Trace.TraceWarning("Couldn't decode ReadRange");
                }
                else
                {
                    Trace.TraceWarning("Confirmed service not handled: " + service.ToString());
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error in ProcessConfirmedServiceRequest: " + ex.Message);
            }
        }