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; } }
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); } } }
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; }
/*****************************************************************************************************/ 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); } } }
/*****************************************************************************************************/ 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); } } }
private void handler_OnReadPropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyReference property, BacnetMaxSegments max_segments) { lock (m_storage) { _logger.LogInformation($"Read property request for {property.ToString()} of {object_id.ToString()} from {adr.ToString()}."); 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); } } }
/*****************************************************************************************************/ 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); } } }
/*****************************************************************************************************/ 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); } } }
/*****************************************************************************************************/ // Create & Delete Object by C. Gunter // OBJECT_ANALOG_INPUT sample 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 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_INPUT: AnalogInput <double> newAI = new AnalogInput <double>(object_id, obj_name, obj_description, obj_value, obj_unit); device.AddBacnetObject(newAI); 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); }
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 OnSubscribeCOV(BacnetClient sender, BacnetAddress adr, byte invoke_id, uint subscriberProcessIdentifier, BacnetObjectId monitoredObjectIdentifier, bool cancellationRequest, bool issueConfirmedNotifications, uint lifetime, BacnetMaxSegments max_segments) { lock (m_lockObject) { try { //create Subscription sub = 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 (m_storage.ReadPropertyAll(sub.monitoredObjectIdentifier, out values)) { 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, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER); } } }
/*****************************************************************************************************/ static 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); } } }
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; }
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); } } }
private static void OnReadPropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyReference property, BacnetMaxSegments max_segments) { lock (m_lockObject) { try { IList <BacnetValue> value; DeviceStorage.ErrorCodes code = 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); } } }
// 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); } } }
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); } } }
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); } } }
public void OnReadPropertyRequest(BacnetClient sender, BacnetAddress adr, byte invoke_id, BacnetObjectId object_id, BacnetPropertyReference property, BacnetMaxSegments max_segments) { lock (BACnetGlobalNetwork.m_storage) { try { IList <BacnetValue> value; DeviceStorage.ErrorCodes code = BACnetGlobalNetwork.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 ex) { Instance.hspi.Log("BACnetDevice Exception in OnReadPropertyRequest " + ex.Message, 2); sender.ErrorResponse(adr, BacnetConfirmedServices.SERVICE_CONFIRMED_READ_PROPERTY, invoke_id, BacnetErrorClasses.ERROR_CLASS_DEVICE, BacnetErrorCodes.ERROR_CODE_OTHER); } } }
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_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); } } }
/*****************************************************************************************************/ 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); } } }