// 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()); } } }
// 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()); } } }