// This method that will be called when the thread is started
        public void BACnetListenerMethod()
        {
            Console.WriteLine("Thread starting for port " + Convert.ToString(BACnet_port));

            while (true)
            {
                Byte[]       received          = new Byte[2000];
                BACnetPacket incomingCRPpacket = new BACnetPacket(_apm, _bnm);

                // Create an IPEndPoint to capture the identity of the sending host.
                IPEndPoint sender       = new IPEndPoint(IPAddress.Any, 0);
                EndPoint   senderRemote = (EndPoint)sender;

                try
                {
                    incomingCRPpacket.length = _bnm.bacnet_listen_socket.ReceiveFrom(received, ref senderRemote);

                    Console.WriteLine("This message was sent from " + ((IPEndPoint)senderRemote).Address.ToString() + "  Port " + ((IPEndPoint)senderRemote).Port.ToString());

                    incomingCRPpacket.directlyConnectedIPEndPointOfDevice = new myIPEndPoint(senderRemote);
                    incomingCRPpacket.buffer = received;

                    // Decode the packet
                    bool decodeOK = incomingCRPpacket.DecodeBACnet(received, incomingCRPpacket.length);

                    if (!decodeOK)
                    {
                        continue;
                    }

                    // log this data
                    PacketLog pkt = new PacketLog(false, (IPEndPoint)senderRemote, incomingCRPpacket);
                    pkt.BACnetPacket = (BACnetPacket)incomingCRPpacket;
                    _bnm.BACnetMessageLog.Enqueue(pkt);


                    // did packet Decode fail to create a device? If so, we are not interested. e.g. Who-Is.

                    if (incomingCRPpacket.srcDevice == null)
                    {
                        _apm.MessageTodo("m0039 - Device not created by packet decode");
                        continue;
                    }


                    _apm.pktQueueToApplication.Enqueue(incomingCRPpacket);
                }
                catch (SocketException)
                {
                    // we expect a socket exception when shutting down
                    System.Console.WriteLine("socket exception occurred");
                }
                catch (System.Threading.ThreadAbortException)
                {
                    System.Console.WriteLine("Thread abort exception occurred (shutting down)");
                }
                catch (Exception efe)
                {
                    // need to catch the inevitable exception when this blocking call is cancelled by the shutdown code
                    _apm.MessagePanic(efe.ToString());
                }
            }
        }
Exemple #2
0
        // This method that will be called when the thread is started
        public void BACnetInsideListener()
        {
            while (true)
            {
                // Byte[] received = new Byte[2000];
                BACnetPacket packet = new BACnetPacket(_apm);

                // Create an IPEndPoint to capture the identity of the sending host.
                IPEndPoint sender       = new IPEndPoint(IPAddress.Any, 0);
                EndPoint   senderRemote = (EndPoint)sender;

                try
                {
                    // bacnet_listen_socket.Receive(received);
                    packet.length = listen_socket.ReceiveFrom(packet.buffer, ref senderRemote);

                    // Console.WriteLine("This message was sent from " + ((IPEndPoint)senderRemote).Address.ToString() + "  Port " + ((IPEndPoint)senderRemote).Port.ToString());
                    // packet.fromBIP = (IPEndPoint) senderRemote;
                    packet.directlyConnectedIPEndPointOfDevice         = new myIPEndPoint();
                    packet.directlyConnectedIPEndPointOfDevice.Port    = ((IPEndPoint)senderRemote).Port;
                    packet.directlyConnectedIPEndPointOfDevice.Address = ((IPEndPoint)senderRemote).Address;

                    // if the packet is from ourselves, discard
                    if (listen_socket.detect_echo_packet(bnm, packet) == true)
                    {
                        continue;
                    }

                    // todo - one day, we will be able to see if this packet was addressed to this host in a broadcast packet, and mark the dadr accordingly, that is, if we care.

                    // todo - remove directlyconnected
                    //packet.srcDevice.adr = new ADR ( packet.directlyConnectedIPEndPointOfDevice ) ;

                    // Make an undecoded copy of the packet for the application layer. This is to ease debugging in the asynch application layer.
                    BACnetPacket appPkt = (BACnetPacket)packet.Clone();

                    // packet.buffer = received;
                    packet.DecodeBACnet();

                    // extract some information from the packet for our caches

                    if (packet.sAdr != null)
                    {
                        lock (_apm.internalRouterInfo)
                        {
                            _apm.internalRouterInfo.AddRoutingTableEntry(packet.sAdr.networkNumber);
                        }
                    }
                    if (packet.routerTableList != null)
                    {
                        lock (_apm.internalRouterInfo)
                        {
                            foreach (RoutingTableEntry re in packet.routerTableList)
                            {
                                // surrounding this because we know of at least one router out there that has illegal network numbers
                                try
                                {
                                    _apm.internalRouterInfo.AddRoutingTableEntry(re.networkNumber);
                                }
                                catch (ProtocolException pe)
                                {
                                    pe.DumpException(_apm);
                                }
                            }
                        }
                    }


                    // display the decoded packet in the UI treeview
                    bnm.newPacketQueue.myEnqueue(packet);

                    // todo, if diagnostics are not running, then this queue will overflow.... hence the check.. find a cleaner method..
                    if (_apm.pktQueueToApplication.Count < 1000)
                    {
                        _apm.pktQueueToApplication.myEnqueue(appPkt);   // notice, this is not a copy of the packet, it is a pointer to the same packet.... kick me if there are problems one day
                    }
                }
                catch (ProtocolException pe)
                {
                    pe.DumpException(_apm);
                }
                catch (SocketException)
                {
                    // need to catch the inevitable exception when this blocking call is cancelled by the shutdown code
                    // ignore, they will happen on shutdown
                }
                catch (ThreadAbortException)
                {
                }
                catch (Exception efe)
                {
                    _apm.MessagePanic(efe.ToString());
                }
            }
        }