Exemple #1
0
        /// <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
        }