private bool GetEnumeratedPropertyValue(ref BacnetDevice device, BacnetEnums.BacnetPropertyId propId, ref uint value) { var property = new Property { Tag = BacnetEnums.BacnetApplicationTag.BacnetApplicationTagNull }; var recipient = new Device { ServerEp = device.IpAddress, Instance = device.InstanceNumber, Network = device.Network, SourceLength = device.SourceLength }; if (!bacStack.SendReadProperty( recipient, -1, // Array[0] is Object Count BacnetEnums.BacnetObjectType.ObjectDevice, propId, property)) { return(false); } if (property.Tag != BacnetEnums.BacnetApplicationTag.BacnetApplicationTagEnumerated) { return(false); } value = property.ValueEnum; return(true); }
/// <summary> /// Sets the property identifier. /// </summary> /// <param name="bytes">The bytes.</param> /// <param name="pos">The position.</param> /// <param name="type">The type.</param> /// <returns></returns> public static uint SetPropertyId(ref byte[] bytes, uint pos, BacnetEnums.BacnetPropertyId type) { var value = (uint)type; if (value <= 255) { bytes[pos++] = 0x19; bytes[pos++] = (byte)type; } else if (value < 65535) { bytes[pos++] = 0x1A; var temp2 = BitConverter.GetBytes(value); bytes[pos++] = temp2[1]; bytes[pos++] = temp2[0]; } return(pos); }
/// <summary> /// Write Property. /// </summary> /// <param name="recipient">The receipient.</param> /// <param name="arrayidx">The arrayidx.</param> /// <param name="objtype">The objtype.</param> /// <param name="objprop">The objprop.</param> /// <param name="property">The property.</param> /// <param name="priority">The priority.</param> /// <returns></returns> public bool SendWriteProperty( Device recipient, int arrayidx, BacnetEnums.BacnetObjectType objtype, BacnetEnums.BacnetPropertyId objprop, Property property, int priority) { // Create and send an Confirmed Request if (recipient == null) { return(false); } if (property == null) { return(false); } var sendBytes = new byte[50]; // BVLL var len = Bvlc.Fill(ref sendBytes, Bvlc.BacnetBvlcFuncUnicastNpdu, 0); // NPDU sendBytes[len++] = BacnetEnums.BacnetProtocolVersion; if (recipient.SourceLength == 0) { sendBytes[len++] = 0x04; // Control flags, no destination address } else { sendBytes[len++] = 0x24; // Control flags, with broadcast or destination } if (recipient.SourceLength > 0) { // Get the (MSTP) Network number (2001) //sendBytes[6] = 0x07; // Destination network address (2001) //sendBytes[7] = 0xD1; var temp2 = BitConverter.GetBytes(recipient.Network); sendBytes[len++] = temp2[1]; sendBytes[len++] = temp2[0]; // Get the MAC address (0x0D) //sendBytes[8] = 0x01; // MAC address length //sendBytes[9] = 0x0D; // Destination MAC layer address var temp4 = BitConverter.GetBytes(recipient.MacAddress); sendBytes[len++] = 0x01; // MAC address length - adjust for other lengths ... sendBytes[len++] = temp4[0]; sendBytes[len++] = 0xFF; // Hop count = 255 } // APDU sendBytes[len++] = 0x00; // Control flags sendBytes[len++] = 0x05; // Max APDU length (1476) // Create invoke counter //sendBytes[len++] = InvokeCounter++; // Invoke ID sendBytes[len++] = (byte)(invokeCounter); invokeCounter = ((invokeCounter + 1) & 0xFF); sendBytes[len++] = 0x0F; // Service Choice: Write Property request // Service Request (var part of APDU): // Set up Object ID (Context Tag) len = Apdu.SetObjectId(ref sendBytes, len, objtype, recipient.Instance); // Set up Property ID (Context Tag) len = Apdu.SetPropertyId(ref sendBytes, len, objprop); // Optional array index goes here if (arrayidx >= 0) { len = Apdu.SetArrayIdx(ref sendBytes, len, arrayidx); } // Set the value to send len = Apdu.SetProperty(ref sendBytes, len, property); //PEP Optional array index goes here // Set priority if (priority > 0) { len = Apdu.SetPriority(ref sendBytes, len, priority); } // Fix the BVLL length sendBytes[3] = (byte)len; var count = 0; var getResponse = false; while (count < BacnetUnicastRequestRepeatCount && !getResponse) { sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, (int)len, recipient.ServerEp); while (!getResponse) { if (sendUdp.Client.Available <= 0) { continue; } //recvBytes = SendUDP.Receive(ref RemoteEP); var sendTo = recipient.ServerEp; var recvBytes = sendUdp.Receive(ref sendTo); var apduOffset = Npdu.Parse(recvBytes, 4); // BVLL is always 4 bytes // Check for APDU response, and decide what to do // 0x - Confirmed Request // 1x - Un-Confirmed Request // 2x - Simple ACK // 3x - Complex ACK // 4x - Segment ACK // 5x - Error // 6x - Reject // 7x - Abort if (recvBytes[apduOffset] != 0x20) { continue; } // Verify the Invoke ID is the same var ic = (byte)(invokeCounter == 0 ? 255 : invokeCounter - 1); if (ic == recvBytes[apduOffset + 1]) { getResponse = true; // This will still execute the finally } } count++; } return(getResponse); // This will still execute the finally }
/// <summary> /// Read Property. /// </summary> /// <param name="recipient">The recipient.</param> /// <param name="arrayidx">The arrayidx.</param> /// <param name="objtype">The objtype.</param> /// <param name="objprop">The objprop.</param> /// <param name="property">The property.</param> /// <returns></returns> public bool SendReadProperty( Device recipient, int arrayidx, BacnetEnums.BacnetObjectType objtype, BacnetEnums.BacnetPropertyId objprop, Property property) { // Create and send an Confirmed Request //value = "(none)"; if (recipient == null) { return(false); } if (property == null) { return(false); } //uint instance = BACnetData.Devices[deviceidx].Instance; var sendBytes = new byte[50]; // BVLL sendBytes[0] = Bvlc.BacnetBvlcTypeBip; sendBytes[1] = Bvlc.BacnetBvlcFuncUnicastNpdu; sendBytes[2] = 0x00; sendBytes[3] = 0x00; // BVLL Length, fix later (24?) // NPDU sendBytes[4] = BacnetEnums.BacnetProtocolVersion; if (recipient.SourceLength == 0) { sendBytes[5] = 0x04; // Control flags, no destination address } else { sendBytes[5] = 0x24; // Control flags, with broadcast or destination address } uint len = 6; if (recipient.SourceLength > 0) { // Get the (MSTP) Network number (2001) var temp2 = BitConverter.GetBytes(recipient.Network); sendBytes[len++] = temp2[1]; sendBytes[len++] = temp2[0]; // Get the MAC address (0x0D) var temp4 = BitConverter.GetBytes(recipient.MacAddress); sendBytes[len++] = 0x01; // MAC address length - adjust for other lengths ... sendBytes[len++] = temp4[0]; sendBytes[len++] = 0xFF; // Hop count = 255 } // APDU sendBytes[len++] = 0x00; // Control flags sendBytes[len++] = 0x05; // Max APDU length (1476) // Create invoke counter sendBytes[len++] = (byte)(invokeCounter); invokeCounter = ((invokeCounter + 1) & 0xFF); sendBytes[len++] = 0x0C; // Service Choice: Read Property request // Service Request (var part of APDU): // Set up Object ID (Context Tag) len = Apdu.SetObjectId(ref sendBytes, len, objtype, recipient.Instance); // Set up Property ID (Context Tag) len = Apdu.SetPropertyId(ref sendBytes, len, objprop); // Optional array index goes here if (arrayidx >= 0) { len = Apdu.SetArrayIdx(ref sendBytes, len, arrayidx); } // Fix the BVLL length sendBytes[3] = (byte)len; var getResponse = false; var count = 0; while (count < BacnetUnicastRequestRepeatCount && !getResponse) { sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, (int)len, recipient.ServerEp); while (!getResponse) { if (sendUdp.Client.Available <= 0) { continue; } //recvBytes = SendUDP.Receive(ref RemoteEP); var sendTo = recipient.ServerEp; var recvBytes = sendUdp.Receive(ref sendTo); var apduOffset = Npdu.Parse(recvBytes, Bvlc.BacnetBvlcHeaderLen); // BVLL is always 4 bytes // Check for APDU response // 0x - Confirmed Request // 1x - Un-Confirmed Request // 2x - Simple ACK // 3x - Complex ACK // 4x - Segment ACK // 5x - Error // 6x - Reject // 7x - Abort if (recvBytes[apduOffset] != 0x30) { continue; } // Verify the Invoke ID is the same var ic = (byte)(invokeCounter == 0 ? 255 : invokeCounter - 1); if (ic != recvBytes[apduOffset + 1]) { continue; } Apdu.ParseProperty(ref recvBytes, apduOffset, property); getResponse = true; // This will still execute the finally } count++; } return(getResponse); }