コード例 #1
0
ファイル: BACnetPacket.cs プロジェクト: kyanha/bacnet-server
        public void EncodeBACnetNew(byte[] outbuf, ref int optr)
        {
            int startBACnetPacket = optr;

            // BVLC Part
            // http://www.bacnetwiki.com/wiki/index.php?title=BACnet_Virtual_Link_Control

            outbuf[optr++] = BACnetEnums.BACNET_BVLC_TYPE_BIP;

            if (npdu.isBroadcast)
            {
                outbuf[optr++] = (byte)BACnetEnums.BACNET_BVLC_FUNCTION.BVLC_ORIGINAL_BROADCAST_NPDU;
            }
            else
            {
                outbuf[optr++] = (byte)BACnetEnums.BACNET_BVLC_FUNCTION.BVLC_ORIGINAL_UNICAST_NPDU;
            }

            int store_length_here = optr;

            optr += 2;

            // Start of NPDU
            // http://www.bacnetwiki.com/wiki/index.php?title=NPDU

            outbuf[optr++] = 0x01;        // Always 1

            int store_NPCI = optr;

            outbuf[optr++] = 0x00;        // Control

            if (npdu.isNPDUmessage)
            {
                outbuf[store_NPCI] |= 0x80;     // Indicating Network Layer Message
            }

            if (npdu.expectingReply)
            {
                outbuf[store_NPCI] |= 0x04;     // todo- magic number
            }

            if (npdu.isBroadcast)
            {
                outbuf[store_NPCI] |= 0x20;     // Control byte - indicate DADR present
                outbuf[optr++]      = 0xff;     // DNET Network - B'cast
                outbuf[optr++]      = 0xff;
                outbuf[optr++]      = 0x00;     // DLEN
            }
            else
            {
                // insert dadr - but only if the device is NOT directly coupled. See page 59. If the device is directly coupled
                // then the ethernet address in the packet will suffice.
                if (!dadr.directlyConnected)
                {
                    // need to insert destination DADR here
                    outbuf[store_NPCI] |= 0x20;         // Control byte - indidate DADR present
                    dadr.Encode(outbuf, ref optr);
                }
            }

            // we are a router, so we need to add source address under most circumstances. (not broadcast who-is)
            if (srcDevice.adr != null)
            {
                outbuf[store_NPCI] |= 0x08;                 // Control byte - indidate SADR present
                srcDevice.adr.Encode(outbuf, ref optr);
            }

            if (npdu.isBroadcast || !dadr.directlyConnected)
            {
                // insert hopcount here.
                hopcount      -= 10;
                outbuf[optr++] = (byte)hopcount;
            }

            // APDU start
            // http://www.bacnetwiki.com/wiki/index.php?title=APDU

            if (apdu_present)
            {
                // APDU start
                // http://www.bacnetwiki.com/wiki/index.php?title=APDU

                for (int i = 0; i < apdu_length; i++)
                {
                    outbuf[optr++] = buffer[apdu_offset + i];        // Encoded APDU type == 01 == Unconfirmed Request
                }
            }
            else if (npdu.isNPDUmessage)
            {
                // Build the Nsdu
                // http://www.bacnetwiki.com/wiki/index.php?title=Network_Layer_Message

                outbuf[optr++] = (byte)npdu.function;

                switch (npdu.function)
                {
                case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
                    break;

                case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_INIT_RT_TABLE:
                    outbuf[optr++] = 0x00;            // Number of port mappings
                    break;

                case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
                    if (numberList != null)
                    {
                        foreach (uint i in numberList)
                        {
                            BACnetLibraryCL.InsertUint16(outbuf, ref optr, i);
                        }
                    }
                    break;

                default:
                    _apm.MessageTodo("m0023 Implement " + npdu.function.ToString());
                    break;
                }
            }
            else
            {
                // build an APDU.
                switch (this.pduType)
                {
                case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
                    switch (this.unconfirmedServiceChoice)
                    {
                    case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM:
                        // APDU start
                        // http://www.bacnetwiki.com/wiki/index.php?title=APDU

                        outbuf[optr++] = 0x10;                // Encoded APDU type == 01 == Unconfirmed Request
                        outbuf[optr++] = 0x00;                // Unconfirmed Service Choice: I-Am

                        // object identifier, device object

                        BACnetObjectIdentifier bnoid = new BACnetObjectIdentifier();

                        bnoid.SetType(BACnetEnums.BACNET_OBJECT_TYPE.OBJECT_DEVICE);
                        _apm.MessageTodo("m0038 - Establish a mechanism to determine our OWN Device ID");
                        bnoid.SetInstance(_apm.ourDeviceId);
                        bnoid.EncodeApplicationTag(outbuf, ref optr);

                        // Maximum APDU length (Application Tag, Integer)
                        Unsigned apdulen = new Unsigned(1476);
                        apdulen.Encode(outbuf, ref optr);

                        // Segmentation supported, (Application Tag, Enum)
                        BACnetSegmentation bsg = new BACnetSegmentation();

                        bsg.Encode(outbuf, ref optr);

                        // Vendor ID, (Application Tag, Integer)
                        BACnetLibraryCL.InsertApplicationTagUint16(outbuf, ref optr, _apm.ourVendorID);
                        break;

                    default:
                        _apm.MessageTodo("m0022 Build missing service type");
                        break;
                    }
                    break;

                default:
                    _apm.MessageTodo("m0021 Build missing PDU type");
                    break;
                }
            }
            outbuf[store_length_here]     = (byte)(((optr - startBACnetPacket) >> 8) & 0xff);
            outbuf[store_length_here + 1] = (byte)((optr - startBACnetPacket) & 0xff);
        }
コード例 #2
0
        // the better method is to populate the pkt structure, then call encode...
        public static void ReadPropertyObjectList_deprecated(BACnetManager bnm, Device device)
        {
            byte[] data = new byte[1024];
            int    optr = 0;

            // BVLC Part
            // http://www.bacnetwiki.com/wiki/index.php?title=BACnet_Virtual_Link_Control

            data[optr++] = BACnetEnums.BACNET_BVLC_TYPE_BIP;                                  // 81
            data[optr++] = (byte)BACnetEnums.BACNET_BVLC_FUNCTION.BVLC_ORIGINAL_UNICAST_NPDU; //0a

            int store_length_here = optr;

            optr += 2;

            // Start of NPDU
            // http://www.bacnetwiki.com/wiki/index.php?title=NPDU

            data[optr++] = 0x01;            //  Version
            data[optr++] = 0x24;            //  NCPI - Dest present, expecting reply

            if (device.adr != null)
            {
                device.adr.Encode(data, ref optr);
            }
            else
            {
                // this means we have an ethernet/IP address for a MAC address. At present
                // we then dont know the network number
                // todo - resolve the network number issue
                ADR tempAdr = new ADR(0, device.directlyConnectedIPEndPointOfDevice);
                tempAdr.Encode(data, ref optr);
            }

            data[optr++] = 0xff;            // Hopcount


            // APDU start
            // http://www.bacnetwiki.com/wiki/index.php?title=APDU


            // Unconfirmed Request
            // Structure described here http://www.bacnetwiki.com/wiki/index.php?title=BACnet-Confirmed-Request-PDU

            data[optr++] = 0x02;            //  PDU Type=0 and SA=1
            data[optr++] = 0x04;            //  Max Resp (Encoded)

            data[optr++] = 0x01;            //  Invoke ID

            data[optr++] = 0x0c;            //  Service Choice 12 = ReadProperty

            // Service Request

            // Object type, instance (Device Object)
            device.deviceObjectID.Encode(data, ref optr);

            // Property Identifier (Object List)

            data[optr++] = 0x19;            //  19  Context Tag: 1, Length/Value/Type: 1
            data[optr++] = 0x4c;            //  4c  Property Identifier: object-list (76)

            BACnetUtil.InsertInt16(data, ref store_length_here, optr);

            bnm.insideSocket.OurSendTo(data, optr, device.packet.directlyConnectedIPEndPointOfDevice);
        }