Exemplo n.º 1
0
        private void DecodeConfirmedService(byte[] apdu_buf)
        {
            if ((apdu_buf[0] & 0x08) != 0)
            {
                _apm.MessageTodo("m0002 Need to implement confirmed service types with seg=1 still");
                return;
            }

            int iptr = 3;

            confirmedServiceChoice       = (BACnetEnums.BACNET_CONFIRMED_SERVICE)apdu_buf[iptr++];
            apduConfirmedServiceTypeFlag = true;

            switch (confirmedServiceChoice)
            {
            case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY:
                // Expecting 2-3 context tags.
                // First, mandatory, context 0, object ID
                objectID = new BACnetObjectIdentifier();
                objectID.DecodeContextTag(apdu_buf, ref iptr);

                // Second, mandatory, Property ID
                propertyID = (BACnetEnums.BACNET_PROPERTY_ID)BACnetEncoding.DecodeTagContextUint(apdu_buf, ref iptr, 1);

                // Third, Array Index, Optional
                if (iptr < apdu_length)
                {
                    arrayIndex        = (int)BACnetEncoding.DecodeTagContextUint(apdu_buf, ref iptr, 2);
                    arrayIndexDecoded = true;
                }
                break;

            default:
                _apm.MessageTodo("m0024 all the other service types");
                break;
            }
        }
Exemplo n.º 2
0
        void DecodeComplexACK(byte[] buf, int offset)
        {
            if ((buf[offset] & 0x0f) != 0)
            {
                throw new Exception("m0020 - Not ready to handle segmented messages yet");
            }

            // invoke ID - ignoring for now

            // Service ACK choice

            BACnetEnums.BACNET_CONFIRMED_SERVICE sc = (BACnetEnums.BACNET_CONFIRMED_SERVICE)buf[offset + 2];
            switch (sc)
            {
            case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY:
                offset += 3;

                // Decode Object ID of the object whos property we are reading

                BACnetObjectIdentifier oid = new BACnetObjectIdentifier(buf, ref offset, BACnetEnums.TAG.CONTEXT, 0);

                // Decode the property ID
                propertyID = (BACnetEnums.BACNET_PROPERTY_ID)BACnetEncoding.DecodeTagContextUint(buf, ref offset, 1);

                // Now decode the Property Value itself. Variable encoding, variable length, etc....

                switch (oid.objectType)
                {
                case BACnetEnums.BACNET_OBJECT_TYPE.OBJECT_DEVICE:
                    switch (propertyID)
                    {
                    case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_LIST:
                        // decode the list of objects
                        // process the opening context tag, 0x3e
                        if (buffer[offset++] != 0x3e)
                        {
                            throw new Exception("m0033 - Opening context tag not found " + buffer[offset - 1].ToString());
                        }

                        objectList = new List <BACnetObjectIdentifier>();

                        // now loop until closing tag found
                        while (buffer[offset] != 0x3f)
                        {
                            // we should get a list of object IDs, add these to our backnet packet object as they are discovered.

                            objectList.Add(new BACnetObjectIdentifier(buffer, ref offset, BACnetEnums.TAG.APPLICATION, BACnetEnums.BACNET_APPLICATION_TAG.BACNET_APPLICATION_TAG_OBJECT_ID));
                        }
                        break;

                    case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_NAME:
                        _apm.MessageTodo("m0032 - Decode object name");
                        break;

                    default:
                        _apm.MessageTodo("m0026 Unimplemented Property ID " + propertyID.ToString());
                        break;
                    }
                    break;

                default:
                    _apm.MessageTodo("m0061 Unhandled object type " + oid.objectType.ToString());
                    break;
                }
                break;

            default:
                _apm.MessageTodo("m0028 - Not ready to deal with this service yet " + sc.ToString());
                return;
            }
        }
Exemplo n.º 3
0
        private bool DecodeUnconfirmedService(byte[] apdu_buf, int apduLen)
        {
            // todo, this code assumes that the service is encoded in postion number one. This is not always the case. Resolve

            if ((apdu_buf[0] & 0x0f) != 0)
            {
                _apm.MessageProtocolError("m0025 this nibble should be zero for Unconfirmed services");
                return(false);
            }

            if (apdu_buf[1] == (byte)BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS)
            {
                // http://www.bacnetwiki.com/wiki/index.php?title=Who-Is

                apduUnconfirmedServiceFlag = true;
                unconfirmedServiceChoice   = BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS;

                if (apduLen != 2)
                {
                    int offset = 2;

                    // means we must have a low and high range..
                    lowRange  = BACnetEncoding.DecodeTagContextUint(apdu_buf, ref offset, 0);
                    highRange = BACnetEncoding.DecodeTagContextUint(apdu_buf, ref offset, 1);
                }

                // and for now, we will assume only workstations issue who-is messages.
                this.srcDevice.type = BACnetEnums.DEVICE_TYPE.Workstation;
            }
            else if (apdu_buf[1] == (byte)BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM)
            {
                apduUnconfirmedServiceFlag = true;
                unconfirmedServiceChoice   = BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM;

                // I-Am described right here: http://www.bacnetwiki.com/wiki/index.php?title=I-Am

                // first encoded entity is the Device Identifier...
                // Encoding described here: http://www.bacnetwiki.com/wiki/index.php?title=Encoding

                // Decode Device Identifier

                int offset = 2;

                srcDevice.deviceObjectID.DecodeApplicationTag(apdu_buf, ref offset);
                Console.WriteLine("This is device: " + srcDevice.deviceObjectID);

                // todo, for now, we will ignore device insance xxx if received
                // and we are the client (bacnet browser )

                srcDevice.packet = this;

                uint maxAPDULen;

                offset += BACnetEncoding.BACnetDecode_uint(apdu_buf, offset, out maxAPDULen);

                Console.WriteLine("Max APDU length accepted: " + maxAPDULen);

                uint segmentation_supported;

                offset += BACnetEncoding.BACnetDecode_uint(apdu_buf, offset, out segmentation_supported);

                Console.WriteLine("Segmentation Supported: " + segmentation_supported);

                srcDevice.SegmentationSupported = (BACnetEnums.BACNET_SEGMENTATION)segmentation_supported;



                uint vendorId;

                offset += BACnetEncoding.BACnetDecode_uint(apdu_buf, offset, out vendorId);

                Console.WriteLine("VendorId: " + vendorId);

                srcDevice.VendorId = vendorId;
            }
            return(true);
        }