예제 #1
0
        public void DownloadFileBySegmentation(BacnetClient comm, BacnetAddress adr, BacnetObjectId object_id, string filename, Action <int> progress_action)
        {
            Cancel = false;

            //open file
            System.IO.FileStream fs = null;
            try
            {
                fs = System.IO.File.OpenWrite(filename);
            }
            catch (Exception ex)
            {
                throw new System.IO.IOException("Couldn't open file", ex);
            }

            BacnetMaxSegments old_segments = comm.MaxSegments;

            comm.MaxSegments        = BacnetMaxSegments.MAX_SEG65;                             //send as many segments as needed
            comm.ProposedWindowSize = Properties.Settings.Default.Segments_ProposedWindowSize; //set by options
            comm.ForceWindowSize    = true;
            try
            {
                int position = 0;
                //uint count = (uint)comm.GetFileBufferMaxSize() * 20;     //this is more realistic
                uint   count       = 50000;                                //this is more difficult
                bool   end_of_file = false;
                byte[] buffer;
                int    buffer_offset;
                while (!end_of_file && !Cancel)
                {
                    //read from device
                    if (!comm.ReadFileRequest(adr, object_id, ref position, ref count, out end_of_file, out buffer, out buffer_offset))
                    {
                        throw new System.IO.IOException("Couldn't read file");
                    }
                    position += (int)count;

                    //write to file
                    if (count > 0)
                    {
                        fs.Write(buffer, buffer_offset, (int)count);
                        if (progress_action != null)
                        {
                            progress_action(position);
                        }
                    }
                }
            }
            finally
            {
                fs.Close();
                comm.MaxSegments     = old_segments;
                comm.ForceWindowSize = false;
            }
        }
예제 #2
0
파일: APDU.cs 프로젝트: vberkaltun/BACnet
        public static int DecodeConfirmedServiceRequest(byte[] buffer, int offset, out BacnetPduTypes type, out BacnetConfirmedServices service,
                                                        out BacnetMaxSegments maxSegments, out BacnetMaxAdpu maxAdpu, out byte invokeId, out byte sequenceNumber, out byte proposedWindowNumber)
        {
            var orgOffset = offset;

            type        = (BacnetPduTypes)buffer[offset++];
            maxSegments = (BacnetMaxSegments)(buffer[offset] & 0xF0);
            maxAdpu     = (BacnetMaxAdpu)(buffer[offset++] & 0x0F);
            invokeId    = buffer[offset++];

            sequenceNumber       = 0;
            proposedWindowNumber = 0;
            if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
            {
                sequenceNumber       = buffer[offset++];
                proposedWindowNumber = buffer[offset++];
            }
            service = (BacnetConfirmedServices)buffer[offset++];

            return(offset - orgOffset);
        }
 static void handler_OnCreateObjectRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, ICollection <BacnetPropertyValue> values, BacnetMaxSegments max_segments)
 {
 }
예제 #4
0
 private static void OnReinitializedDevice(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetReinitializedStates state, string password, BacnetMaxSegments max_segments)
 {
     Trace.TraceInformation("So you wanna reboot me, eh? Pfff! (" + state.ToString() + ")");
     sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_REINITIALIZE_DEVICE, invoke_id);
 }
예제 #5
0
        private static void HandleSegmentationResponse(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetMaxSegments max_segments, Action <BacnetClient.Segmentation> transmit)
        {
            BacnetClient.Segmentation segmentation = sender.GetSegmentBuffer(max_segments);

            //send first
            transmit(segmentation);

            if (segmentation == null || segmentation.buffer.result == System.IO.BACnet.Serialize.EncodeResult.Good)
            {
                return;
            }

            //start new thread to handle the segment sequence
            System.Threading.ThreadPool.QueueUserWorkItem((o) =>
            {
                byte old_max_info_frames       = sender.Transport.MaxInfoFrames;
                sender.Transport.MaxInfoFrames = segmentation.window_size;      //increase max_info_frames, to increase throughput. This might be against 'standard'
                while (true)
                {
                    bool more_follows = (segmentation.buffer.result & System.IO.BACnet.Serialize.EncodeResult.NotEnoughBuffer) > 0;

                    //wait for segmentACK
                    if ((segmentation.sequence_number - 1) % segmentation.window_size == 0 || !more_follows)
                    {
                        if (!sender.WaitForAllTransmits(sender.TransmitTimeout))
                        {
                            Trace.TraceWarning("Transmit timeout");
                            break;
                        }
                        byte current_number = segmentation.sequence_number;
                        if (!sender.WaitForSegmentAck(adr, invoke_id, segmentation, sender.Timeout))
                        {
                            Trace.TraceWarning("Didn't get segmentACK");
                            break;
                        }
                        if (segmentation.sequence_number != current_number)
                        {
                            Trace.WriteLine("Oh, a retransmit", null);
                            more_follows = true;
                        }
                    }
                    else
                    {
                        //a negative segmentACK perhaps
                        byte current_number = segmentation.sequence_number;
                        sender.WaitForSegmentAck(adr, invoke_id, segmentation, 0);      //don't wait
                        if (segmentation.sequence_number != current_number)
                        {
                            Trace.WriteLine("Oh, a retransmit", null);
                            more_follows = true;
                        }
                    }

                    if (more_follows)
                    {
                        lock (m_lockObject) transmit(segmentation);
                    }
                    else
                    {
                        break;
                    }
                }
                sender.Transport.MaxInfoFrames = old_max_info_frames;
            });
        }
        /*****************************************************************************************************/
        // Create & Delete Object by C. Gunter
        //  OBJECT_ANALOG_VALUE sample
        static void handler_OnCreateObjectRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, ICollection <BacnetPropertyValue> values, BacnetMaxSegments max_segments)
        {
            // simple not all errortypes!!!!!!!! and for now only Analog inputs
            if (device.FindBacnetObject(object_id) != null)
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_CREATE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS);
                return;
            }

            // some default values
            string        obj_name        = object_id.type.ToString() + object_id.instance.ToString();
            string        obj_description = "Sample for you by C. Günter";
            BacnetUnitsId obj_unit        = BacnetUnitsId.UNITS_NO_UNITS;
            double        obj_value       = 0;

            // normally only needs objid, these properties values are sent or not by the client
            if (values != null)
            {
                foreach (BacnetPropertyValue value in values)
                {
                    switch (value.property.propertyIdentifier)
                    {
                    case (uint)BacnetPropertyIds.PROP_DESCRIPTION:
                        obj_description = (string)value.value[0].Value;
                        break;

                    case (uint)BacnetPropertyIds.PROP_OBJECT_NAME:
                        obj_name = (string)value.value[0].Value;
                        break;

                    case (uint)BacnetPropertyIds.PROP_UNITS:
                        obj_unit = (BacnetUnitsId)value.value[0].Value;
                        break;

                    case (uint)BacnetPropertyIds.PROP_PRESENT_VALUE:
                        try
                        {
                            obj_value = Convert.ToDouble(value.value[0].Value);     // double is the simplest, quite all values convertible to it
                        }
                        catch { }
                        break;
                    }
                }
            }
            //add to device
            switch (object_id.type)
            {
            case BacnetObjectTypes.OBJECT_ANALOG_VALUE:
                AnalogValue <double> newAV = new AnalogValue <double>(object_id, obj_name, obj_description, obj_value, obj_unit, false);
                newAV.AcceptDeleteObject = true;
                device.AddBacnetObject(newAV);
                break;

            /* to be added by yourself according to your project requirement
             */
            default:
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_CREATE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNSUPPORTED_OBJECT_TYPE);
                return;
            }
            //send ack that has been created
            sender.CreateObjectResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), object_id);
        }
        /*****************************************************************************************************/
        static void handler_OnWritePropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyValue value, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject bacobj = device.FindBacnetObject(object_id);
                if (bacobj != null)
                {
                    ErrorCodes error = bacobj.WritePropertyValue(sender, adr, value, true);
                    if (error == ErrorCodes.Good)
                    {
                        sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id);
                    }
                    else
                    {
                        BacnetErrorCodes bacEr = BacnetErrorCodes.ERROR_CODE_OTHER;
                        if (error == ErrorCodes.WriteAccessDenied)
                        {
                            bacEr = BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED;
                        }
                        if (error == ErrorCodes.OutOfRange)
                        {
                            bacEr = BacnetErrorCodes.ERROR_CODE_VALUE_OUT_OF_RANGE;
                        }

                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, bacEr);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT);
                }
            }
        }
예제 #8
0
 public static byte GetSegmentsCount(BacnetMaxSegments max_segments)
 {
     switch (max_segments)
     {
         case BacnetMaxSegments.MAX_SEG0:
             return 0;
         case BacnetMaxSegments.MAX_SEG2:
             return 2;
         case BacnetMaxSegments.MAX_SEG4:
             return 4;
         case BacnetMaxSegments.MAX_SEG8:
             return 8;
         case BacnetMaxSegments.MAX_SEG16:
             return 16;
         case BacnetMaxSegments.MAX_SEG32:
             return 32;
         case BacnetMaxSegments.MAX_SEG64:
             return 64;
         case BacnetMaxSegments.MAX_SEG65:
             return 0xFF;
         default:
             throw new Exception("Not an option");
     }
 }
예제 #9
0
 private void m_comm_OnSegment(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invoke_id, BacnetMaxSegments max_segments, BacnetMaxApdu max_adpu, byte sequence_number, bool first, bool more_follows, byte[] buffer, int offset, int length)
 {
     if (invoke_id == m_wait_invoke_id)
     {
         Segmented = true;
         ((System.Threading.ManualResetEvent)AsyncWaitHandle).Set();
     }
 }
예제 #10
0
        /// <summary>
        /// This is a simple handling that stores all segments in memory and assembles them when done
        /// </summary>
        private void PerformDefaultSegmentHandling(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invoke_id, BacnetMaxSegments max_segments, BacnetMaxAdpu max_adpu, byte sequence_number, bool first, bool more_follows, byte[] buffer, int offset, int length)
        {
            if (first)
            {
                //clear any leftover segments
                m_segments.Clear();

                //copy buffer + encode new adpu header
                type &= ~BacnetPduTypes.SEGMENTED_MESSAGE;
                int adpu_header_len = 3;
                if ((type & BacnetPduTypes.PDU_TYPE_MASK) == BacnetPduTypes.PDU_TYPE_CONFIRMED_SERVICE_REQUEST) adpu_header_len = 4;
                byte[] copy = new byte[length + adpu_header_len];
                Array.Copy(buffer, offset, copy, adpu_header_len, length);
                if ((type & BacnetPduTypes.PDU_TYPE_MASK) == BacnetPduTypes.PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
                    APDU.EncodeConfirmedServiceRequest(new EncodeBuffer(copy, 0), type, service, max_segments, max_adpu, invoke_id, 0, 0);
                else
                    APDU.EncodeComplexAck(new EncodeBuffer(copy, 0), type, service, invoke_id, 0, 0);
                m_segments.AddLast(copy);       //doesn't include BVLC or NPDU
            }
            else
            {
                //copy only content part
                byte[] copy = new byte[length];
                Array.Copy(buffer, offset, copy, 0, copy.Length);
                m_segments.AddLast(copy);
            }

            //process when finished
            if (!more_follows)
            {
                //assemble whole part
                byte[] apdu_buffer = AssembleSegments();
                m_segments.Clear();

                //process
                ProcessApdu(adr, type, apdu_buffer, 0, apdu_buffer.Length);
            }
        }
예제 #11
0
        private void ProcessSegment(BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invoke_id, BacnetMaxSegments max_segments, BacnetMaxAdpu max_adpu, bool server, byte sequence_number, byte proposed_window_number, byte[] buffer, int offset, int length)
        {
            bool first = false;
            if (sequence_number == 0 && m_last_sequence_number == 0)
            {
                first = true;
            }
            else
            {
                //send negative ack
                if (sequence_number != (m_last_sequence_number + 1))
                {
                    SegmentAckResponse(adr, true, server, invoke_id, m_last_sequence_number, proposed_window_number);
                    Trace.WriteLine("Segment sequence out of order", null);
                    return;
                }
            }
            m_last_sequence_number = sequence_number;

            bool more_follows = (type & BacnetPduTypes.MORE_FOLLOWS) == BacnetPduTypes.MORE_FOLLOWS;
            if (!more_follows) m_last_sequence_number = 0;  //reset last sequence_number

            //send ACK
            if ((sequence_number % proposed_window_number) == 0 || !more_follows)
            {
                if (m_force_window_size) proposed_window_number = m_proposed_window_size;
                SegmentAckResponse(adr, false, server, invoke_id, sequence_number, proposed_window_number);
            }

            //Send on
            if (OnSegment != null)
                OnSegment(this, adr, type, service, invoke_id, max_segments, max_adpu, sequence_number, first, more_follows, buffer, offset, length);

            //default segment assembly. We run this separately from the above handler, to make sure that it comes after!
            if (m_default_segmentation_handling)
                PerformDefaultSegmentHandling(this, adr, type, service, invoke_id, max_segments, max_adpu, sequence_number, first, more_follows, buffer, offset, length);
        }
예제 #12
0
 private void m_comm_OnSegment(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invoke_id, BacnetMaxSegments max_segments, BacnetMaxAdpu max_adpu, byte sequence_number, bool first, bool more_follows, byte[] buffer, int offset, int length)
 {
     if (invoke_id == m_wait_invoke_id)
     {
         Segmented = true;
         ((System.Threading.ManualResetEvent)AsyncWaitHandle).Set();
     }
 }
예제 #13
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);
            }
        }
예제 #14
0
 public Segmentation GetSegmentBuffer(BacnetMaxSegments max_segments)
 {
     if (max_segments == BacnetMaxSegments.MAX_SEG0) return null;
     Segmentation ret = new Segmentation();
     ret.buffer = GetEncodeBuffer(m_client.HeaderLength);
     ret.max_segments = GetSegmentsCount(max_segments);
     ret.window_size = m_proposed_window_size;
     return ret;
 }
예제 #15
0
 /*****************************************************************************************************/
 static void handler_OnReadPropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyReference property, BacnetMaxSegments max_segments)
 {
     lock (m_storage)
     {
         try
         {
             IList <BacnetValue>      value;
             DeviceStorage.ErrorCodes code = m_storage.ReadProperty(object_id, (BacnetPropertyIds)property.propertyIdentifier, property.propertyArrayIndex, out value);
             if (code == DeviceStorage.ErrorCodes.Good)
             {
                 sender.ReadPropertyResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), object_id, property, value);
             }
             else
             {
                 sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
             }
         }
         catch (Exception)
         {
             sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
         }
     }
 }
예제 #16
0
        public static void EncodeConfirmedServiceRequest(EncodeBuffer buffer, BacnetPduTypes type, BacnetConfirmedServices service, BacnetMaxSegments max_segments, BacnetMaxApdu max_adpu, byte invoke_id, byte sequence_number, byte proposed_window_size)
        {
            buffer.buffer[buffer.offset++] = (byte)type;
            buffer.buffer[buffer.offset++] = (byte)((byte)max_segments | (byte)max_adpu);
            buffer.buffer[buffer.offset++] = invoke_id;

            if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) > 0)
            {
                buffer.buffer[buffer.offset++] = sequence_number;
                buffer.buffer[buffer.offset++] = proposed_window_size;
            }
            buffer.buffer[buffer.offset++] = (byte)service;
        }
예제 #17
0
        void handler_OnCOVNotification(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint subscriberProcessIdentifier, BacnetObjectId initiatingDeviceIdentifier, BacnetObjectId monitoredObjectIdentifier, uint timeRemaining, bool need_confirm, ICollection <BacnetPropertyValue> values, BacnetMaxSegments max_segments)
        {
            foreach (BacnetPropertyValue value in values)
            {
                switch ((BacnetPropertyIds)value.property.propertyIdentifier)
                {
                case BacnetPropertyIds.PROP_PRESENT_VALUE:
                    Debug.WriteLine($"Got {value.value[0].Value} from {monitoredObjectIdentifier}");
                    this.SendTelemtry(value, monitoredObjectIdentifier);
                    break;

                case BacnetPropertyIds.PROP_STATUS_FLAGS:
                    string status_text = "";
                    if (value.value != null && value.value.Count > 0)
                    {
                        BacnetStatusFlags status = (BacnetStatusFlags)((BacnetBitString)value.value[0].Value).ConvertToInt();
                        if ((status & BacnetStatusFlags.STATUS_FLAG_FAULT) == BacnetStatusFlags.STATUS_FLAG_FAULT)
                        {
                            status_text += "FAULT,";
                        }
                        else if ((status & BacnetStatusFlags.STATUS_FLAG_IN_ALARM) == BacnetStatusFlags.STATUS_FLAG_IN_ALARM)
                        {
                            status_text += "ALARM,";
                        }
                        else if ((status & BacnetStatusFlags.STATUS_FLAG_OUT_OF_SERVICE) == BacnetStatusFlags.STATUS_FLAG_OUT_OF_SERVICE)
                        {
                            status_text += "OOS,";
                        }
                        else if ((status & BacnetStatusFlags.STATUS_FLAG_OVERRIDDEN) == BacnetStatusFlags.STATUS_FLAG_OVERRIDDEN)
                        {
                            status_text += "OR,";
                        }
                    }
                    if (status_text != "")
                    {
                        Debug.WriteLine(status_text);
                    }
                    break;

                default:
                    //got something else? ignore it
                    break;
                }
            }

            if (need_confirm)
            {
                sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_COV_NOTIFICATION, invoke_id);
            }
        }
예제 #18
0
        private static void OnAtomicReadFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint count, BacnetMaxSegments max_segments)
        {
            lock (m_lockObject)
            {
                try
                {
                    if (object_id.Type != BacnetObjectTypes.OBJECT_FILE)
                    {
                        throw new Exception("File Reading on non file objects ... bah!");
                    }
                    else if (object_id.Instance != 0)
                    {
                        throw new Exception("Don't know this file");
                    }

                    //this is a test file for performance measuring
                    int  filesize    = m_storage.ReadPropertyValue(object_id, BacnetPropertyIds.PROP_FILE_SIZE);    //test file is ~10mb
                    bool end_of_file = (position + count) >= filesize;
                    count = (uint)Math.Min(count, filesize - position);
                    int max_filebuffer_size = sender.GetFileBufferMaxSize();
                    if (count > max_filebuffer_size && max_segments > 0)
                    {
                        //create segmented message!!!
                    }
                    else
                    {
                        count = (uint)Math.Min(count, max_filebuffer_size);     //trim
                    }

                    //fill file with bogus content
                    byte[] file_buffer = new byte[count];
                    byte[] bogus       = new byte[] { (byte)'F', (byte)'I', (byte)'L', (byte)'L' };
                    for (int i = 0; i < count; i += bogus.Length)
                    {
                        Array.Copy(bogus, 0, file_buffer, i, Math.Min(bogus.Length, count - i));
                    }

                    //send
                    HandleSegmentationResponse(sender, adr, invoke_id, max_segments, (seg) =>
                    {
                        sender.ReadFileResponse(adr, invoke_id, seg, position, count, end_of_file, file_buffer);
                    });
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        /*****************************************************************************************************/
        static void handler_OnSubscribeCOVProperty(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint subscriberProcessIdentifier, BacnetObjectId monitoredObjectIdentifier, BacnetPropertyReference monitoredProperty, bool cancellationRequest, bool issueConfirmedNotifications, uint lifetime, float covIncrement, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject bacobj = device.FindBacnetObject(monitoredObjectIdentifier);
                if (bacobj != null)
                {
                    //create
                    Subscription sub = SubscriptionManager.HandleSubscriptionRequest(sender, adr, invoke_id, subscriberProcessIdentifier, monitoredObjectIdentifier, monitoredProperty.propertyIdentifier, cancellationRequest, issueConfirmedNotifications, lifetime, covIncrement);

                    //send confirm
                    sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, invoke_id);

                    //also send first values
                    if (!cancellationRequest)
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem((o) =>
                        {
                            IList <BacnetValue> _values;
                            bacobj.ReadPropertyValue(sender, adr, monitoredProperty, out _values);

                            List <BacnetPropertyValue> values = new List <BacnetPropertyValue>();
                            BacnetPropertyValue tmp           = new BacnetPropertyValue();
                            tmp.property = sub.monitoredProperty;
                            tmp.value    = _values;
                            values.Add(tmp);

                            sender.Notify(adr, sub.subscriberProcessIdentifier, deviceId, sub.monitoredObjectIdentifier, (uint)sub.GetTimeRemaining(), sub.issueConfirmedNotifications, values);
                        }, null);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #20
0
        private static void OnAtomicWriteFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint block_count, byte[][] blocks, int[] counts, BacnetMaxSegments max_segments)
        {
            lock (m_lockObject)
            {
                try
                {
                    if (object_id.Type != BacnetObjectTypes.OBJECT_FILE)
                    {
                        throw new Exception("File Reading on non file objects ... bah!");
                    }
                    else if (object_id.Instance != 0)
                    {
                        throw new Exception("Don't know this file");
                    }

                    //this is a test file for performance measuring
                    //don't do anything with the content

                    //adjust size though
                    int filesize     = m_storage.ReadPropertyValue(object_id, BacnetPropertyIds.PROP_FILE_SIZE);
                    int new_filesize = position + counts[0];
                    if (new_filesize > filesize)
                    {
                        m_storage.WritePropertyValue(object_id, BacnetPropertyIds.PROP_FILE_SIZE, new_filesize);
                    }
                    if (counts[0] == 0)
                    {
                        m_storage.WritePropertyValue(object_id, BacnetPropertyIds.PROP_FILE_SIZE, 0);                      //clear file
                    }
                    //send confirm
                    HandleSegmentationResponse(sender, adr, invoke_id, max_segments, (seg) =>
                    {
                        sender.WriteFileResponse(adr, invoke_id, seg, position);
                    });
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        /*****************************************************************************************************/
        static void handler_OnReadPropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyReference property, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject bacobj = device.FindBacnetObject(object_id);

                if (bacobj != null)
                {
                    IList <BacnetValue> value;
                    ErrorCodes          error = bacobj.ReadPropertyValue(sender, adr, property, out value);
                    if (error == ErrorCodes.Good)
                    {
                        sender.ReadPropertyResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), object_id, property, value);
                    }
                    else
                    if (error == ErrorCodes.IndexNotExist)
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_PROPERTY, BacnetErrorCodes.ERROR_CODE_INVALID_ARRAY_INDEX);
                    }
                    else
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_UNKNOWN_PROPERTY);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT);
                }
            }
        }
예제 #22
0
 private static void OnWritePropertyMultipleRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, ICollection <BacnetPropertyValue> values, BacnetMaxSegments max_segments)
 {
     lock (m_lockObject)
     {
         try
         {
             m_storage.WritePropertyMultiple(object_id, values);
             sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, invoke_id);
         }
         catch (Exception)
         {
             sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
         }
     }
 }
        static void handler_OnDeleteObjectRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetMaxSegments max_segments)
        {
            //check if exists; if doesn't send error Unknown_Object
            if (device.FindBacnetObject(object_id) == null)
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DELETE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT);
                return;
            }

            //remove from device and send ACK normally there should be no error!!!!!!!
            // Attribut AcceptDeleteObject should be true for deletable objects
            if (device.RemoveBacnetObject(object_id) == true)
            {
                sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DELETE_OBJECT, invoke_id);
            }
            else
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DELETE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED);
            }
            return;
        }
예제 #24
0
        private static void OnWritePropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyValue value, BacnetMaxSegments max_segments)
        {
            lock (m_lockObject)
            {
                try
                {
                    // Modif FC

                    DeviceStorage.ErrorCodes code = m_storage.WriteCommandableProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.value[0], value.priority);

                    if (code == DeviceStorage.ErrorCodes.NotForMe)
                    {
                        code = m_storage.WriteProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.property.propertyArrayIndex, value.value);
                    }

                    if (code == DeviceStorage.ErrorCodes.Good)
                    {
                        sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id);
                    }
                    else
                    if (code == DeviceStorage.ErrorCodes.WriteAccessDenied)
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED);
                    }
                    else
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                    }
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #25
0
        private static void OnSubscribeCOVProperty(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint subscriberProcessIdentifier, BacnetObjectId monitoredObjectIdentifier, BacnetPropertyReference monitoredProperty, bool cancellationRequest, bool issueConfirmedNotifications, uint lifetime, float covIncrement, BacnetMaxSegments max_segments)
        {
            lock (m_lockObject)
            {
                try
                {
                    //create
                    Subscription sub = HandleSubscriptionRequest(sender, adr, invoke_id, subscriberProcessIdentifier, monitoredObjectIdentifier, (uint)BacnetPropertyIds.PROP_ALL, cancellationRequest, issueConfirmedNotifications, lifetime, covIncrement);

                    //send confirm
                    sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, invoke_id);

                    //also send first values
                    if (!cancellationRequest)
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem((o) =>
                        {
                            IList <BacnetValue> _values;
                            m_storage.ReadProperty(sub.monitoredObjectIdentifier, (BacnetPropertyIds)sub.monitoredProperty.propertyIdentifier, sub.monitoredProperty.propertyArrayIndex, out _values);
                            List <BacnetPropertyValue> values = new List <BacnetPropertyValue>();
                            BacnetPropertyValue tmp           = new BacnetPropertyValue();
                            tmp.property = sub.monitoredProperty;
                            tmp.value    = _values;
                            values.Add(tmp);
                            if (!sender.Notify(adr, sub.subscriberProcessIdentifier, m_storage.DeviceId, sub.monitoredObjectIdentifier, (uint)sub.GetTimeRemaining(), sub.issueConfirmedNotifications, values))
                            {
                                Trace.TraceError("Couldn't send notify");
                            }
                        }, null);
                    }
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #26
0
        /*****************************************************************************************************/
        void handler_OnSubscribeCOV(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint subscriberProcessIdentifier, BacnetObjectId monitoredObjectIdentifier, bool cancellationRequest, bool issueConfirmedNotifications, uint lifetime, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject bacobj = device.FindBacnetObject(monitoredObjectIdentifier);
                if (bacobj != null)
                {
                    //create
                    Subscription sub = SubscriptionManager.HandleSubscriptionRequest(sender, adr, invoke_id, subscriberProcessIdentifier, monitoredObjectIdentifier, (uint)BacnetPropertyIds.PROP_ALL, cancellationRequest, issueConfirmedNotifications, lifetime, 0);

                    //send confirm
                    sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV, invoke_id);

                    //also send first values
                    if (!cancellationRequest)
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem((o) =>
                        {
                            IList <BacnetPropertyValue> values;
                            if (bacobj.ReadPropertyAll(sender, adr, out values))
                            {
                                sender.Notify(adr, sub.subscriberProcessIdentifier, deviceId, sub.monitoredObjectIdentifier, (uint)sub.GetTimeRemaining(), sub.issueConfirmedNotifications, values);
                            }
                        }, null);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_SUBSCRIBE_COV, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #27
0
        private static void OnDeviceCommunicationControl(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint time_duration, uint enable_disable, string password, BacnetMaxSegments max_segments)
        {
            switch (enable_disable)
            {
            case 0:
                Trace.TraceInformation("Enable communication? Sure!");
                sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, invoke_id);
                break;

            case 1:
                Trace.TraceInformation("Disable communication? ... smile and wave (ignored)");
                sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, invoke_id);
                break;

            case 2:
                Trace.TraceWarning("Disable initiation? I don't think so!");
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                break;

            default:
                Trace.TraceError("Now, what is this device_communication code: " + enable_disable + "!!!!");
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                break;
            }
        }
예제 #28
0
        void handler_OnDeleteObjectRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetMaxSegments max_segments)
        {
            //check if exists; if doesn't send error Unknown_Object
            if (device.FindBacnetObject(object_id) == null)
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_CREATE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT);
                return;
            }

            // check if objecttype is allowed to be deleted, like for example Device switch() for adding more types which cant be deleted
            // Device not removable, no need to check
            switch (object_id.type)
            {
            case BacnetObjectTypes.OBJECT_ACCESS_DOOR:      // just to shows how to do
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_CREATE_OBJECT, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED);
                return;

            default:
                break;
            }
            //remove from device and send ACK normally there should be no error!!!!!!!
            if (device.RemoveBacnetObject(object_id) == true)
            {
                sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_DELETE_OBJECT, invoke_id);
            }
            else
            {
                Console.WriteLine("unknown Error while deleting object!");
            }
            return;
        }
예제 #29
0
        private static void OnWritePropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyValue value, BacnetMaxSegments max_segments)
        {
            BacnetPropertyIds PropId = (BacnetPropertyIds)value.property.propertyIdentifier;

            bool AllowWrite =
                (object_id.Equals("OBJECT_ANALOG_VALUE:0") && (PropId == BacnetPropertyIds.PROP_OUT_OF_SERVICE)) ||
                (object_id.Equals("OBJECT_ANALOG_VALUE:0") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_ANALOG_VALUE:1") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_ANALOG_VALUE:2") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_ANALOG_VALUE:3") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_CHARACTERSTRING_VALUE:1") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_CHARACTERSTRING_VALUE:2") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_CHARACTERSTRING_VALUE:3") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE)) ||
                (object_id.Equals("OBJECT_MULTI_STATE_VALUE:0") && (PropId == BacnetPropertyIds.PROP_PRESENT_VALUE));

            if (AllowWrite == false)
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED);
                return;
            }

            lock (m_lockObject)
            {
                try
                {
                    // Modif FC

                    DeviceStorage.ErrorCodes code = m_storage.WriteCommandableProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.value[0], value.priority);

                    if (code == DeviceStorage.ErrorCodes.NotForMe)
                    {
                        code = m_storage.WriteProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.property.propertyArrayIndex, value.value);
                    }

                    if (code == DeviceStorage.ErrorCodes.Good)
                    {
                        sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id);
                    }
                    else
                    if (code == DeviceStorage.ErrorCodes.WriteAccessDenied)
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED);
                    }
                    else
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                    }
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        private static void handler_OnAtomicReadFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint count, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject File = device.FindBacnetObject(object_id);
                if (File is BacnetFile)
                {
                    try
                    {
                        BacnetFile f = (BacnetFile)File;

                        int  filesize    = (int)f.PROP_FILE_SIZE;
                        bool end_of_file = (position + count) >= filesize;
                        count = (uint)Math.Min(count, filesize - position);
                        int max_filebuffer_size = sender.GetFileBufferMaxSize();
                        if (count > max_filebuffer_size && max_segments > 0)
                        {
                            //create segmented message!!!
                        }
                        else
                        {
                            count = (uint)Math.Min(count, max_filebuffer_size);     //trim
                        }

                        byte[] file_buffer = f.ReadFileBlock(position, (int)count);
                        sender.ReadFileResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), position, count, end_of_file, file_buffer);
                    }
                    catch (Exception)
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_READ_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #31
0
        /*****************************************************************************************************/
        static void handler_OnWritePropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyValue value, BacnetMaxSegments max_segments)
        {
            // only OBJECT_ANALOG_VALUE:0.PROP_PRESENT_VALUE could be write in this sample code
            if ((object_id.type != BacnetObjectTypes.OBJECT_ANALOG_VALUE) || (object_id.instance != 0) || ((BacnetPropertyIds)value.property.propertyIdentifier != BacnetPropertyIds.PROP_PRESENT_VALUE))
            {
                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED);
                return;
            }

            lock (m_storage)
            {
                try
                {
                    DeviceStorage.ErrorCodes code = m_storage.WriteCommandableProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.value[0], value.priority);
                    if (code == DeviceStorage.ErrorCodes.NotForMe)
                    {
                        code = m_storage.WriteProperty(object_id, (BacnetPropertyIds)value.property.propertyIdentifier, value.property.propertyArrayIndex, value.value);
                    }

                    if (code == DeviceStorage.ErrorCodes.Good)
                    {
                        sender.SimpleAckResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id);
                    }
                    else
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                    }
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_WRITE_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        // Here something could be done to avoid a to big fill to be written on the disk
        private static void handler_OnAtomicWriteFileRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, bool is_stream, BacnetObjectId object_id, int position, uint block_count, byte[][] blocks, int[] counts, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject File = device.FindBacnetObject(object_id);
                if (File is BacnetFile)
                {
                    try
                    {
                        BacnetFile f = (BacnetFile)File;

                        if (f.PROP_READ_ONLY == false)
                        {
                            int currentposition = position;
                            for (int i = 0; i < block_count; i++)
                            {
                                f.WriteFileBlock(blocks[i], currentposition, counts[i]);
                                currentposition += counts[i];
                            }
                            sender.WriteFileResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), position);
                        }
                        else
                        {
                            sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_WRITE_ACCESS_DENIED);
                        }
                    }
                    catch (Exception)
                    {
                        sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
예제 #33
0
        /*****************************************************************************************************/
        static void handler_OnReadPropertyMultipleRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, IList <BacnetReadAccessSpecification> properties, BacnetMaxSegments max_segments)
        {
            lock (m_storage)
            {
                try
                {
                    IList <BacnetPropertyValue>   value;
                    List <BacnetReadAccessResult> values = new List <BacnetReadAccessResult>();
                    foreach (BacnetReadAccessSpecification p in properties)
                    {
                        if (p.propertyReferences.Count == 1 && p.propertyReferences[0].propertyIdentifier == (uint)BacnetPropertyIds.PROP_ALL)
                        {
                            if (!m_storage.ReadPropertyAll(p.objectIdentifier, out value))
                            {
                                sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROP_MULTIPLE, invoke_id, BacnetErrorClasses.ERROR_CLASS_OBJECT, BacnetErrorCodes.ERROR_CODE_UNKNOWN_OBJECT);
                                return;
                            }
                        }
                        else
                        {
                            m_storage.ReadPropertyMultiple(p.objectIdentifier, p.propertyReferences, out value);
                        }
                        values.Add(new BacnetReadAccessResult(p.objectIdentifier, value));
                    }

                    sender.ReadPropertyMultipleResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), values);
                }
                catch (Exception)
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROP_MULTIPLE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        /*****************************************************************************************************/
        static void handler_OnReadRange(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId objectId, BacnetPropertyReference property, System.IO.BACnet.Serialize.BacnetReadRangeRequestTypes requestType, uint position, DateTime time, int count, BacnetMaxSegments max_segments)
        {
            lock (device)
            {
                BaCSharpObject trend = device.FindBacnetObject(objectId);

                if (trend is TrendLog)
                {
                    BacnetResultFlags status;
                    byte[]            application_data = (trend as TrendLog).GetEncodedTrends(position, count, out status);

                    if (application_data != null)
                    {
                        //send
                        sender.ReadRangeResponse(adr, invoke_id, sender.GetSegmentBuffer(max_segments), objectId, property, status, (uint)count, application_data, requestType, position);
                    }
                }
                else
                {
                    sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_RANGE, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER);
                }
            }
        }
        /// <summary>
        /// Handler to get COV notification and process further
        /// </summary>
        private void handler_OnCOVNotification(BacnetClient foBacnetClient, BacnetAddress foBacnetAddress, byte foInvokeid,
                                               uint fisubscriberProcessIdentifier, BacnetObjectId foInitiatingDeviceIdentifier, BacnetObjectId foMonitoredObjectIdentifier,
                                               uint fiTimeRemaining, bool fbNeedConfirm, ICollection <BacnetPropertyValue> foBacnetPropertyValue, BacnetMaxSegments foBacnetMaxSegments)
        {
            foreach (BacnetPropertyValue value in foBacnetPropertyValue)
            {
                switch ((BacnetPropertyIds)value.property.propertyIdentifier)
                {
                case BacnetPropertyIds.PROP_PRESENT_VALUE:
                    COVChangesToUI(value.value[0].ToString());
                    break;

                default:
                    ////got something else? ignore it
                    break;
                }
            }
        }
예제 #36
0
        private void OnSegment(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetConfirmedServices service, byte invokeId, BacnetMaxSegments maxSegments, BacnetMaxAdpu maxAdpu, byte sequenceNumber, bool first, bool moreFollows, byte[] buffer, int offset, int length)
        {
            if (invokeId != _waitInvokeId)
            {
                return;
            }

            Segmented = true;
            _waitHandle.Set();
        }