// Returns reference to a network node, creating one if necessary myTreeNode EstablishTreeNodeNet(BACnetManager bnm, BACnetPacket pkt) { // return reference if it is found. for (int i = 0; i < this.TreeViewOnUI.Nodes.Count; i++) { myTreeNode tnNetwork = (myTreeNode)this.TreeViewOnUI.Nodes[i]; if (tnNetwork.networkNumber == pkt.srcDevice.adr.networkNumber) { tnNetwork.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; return(tnNetwork); } } // not found, so create it myTreeNode newNode = new myTreeNode(); if (pkt.srcDevice.adr.directlyConnected == true) { newNode.Text = "Directly Connected Network ( " + pkt.srcDevice.adr.networkNumber + " )"; } else { newNode.Text = "Network " + pkt.srcDevice.adr.networkNumber; } newNode.networkNumber = pkt.srcDevice.adr.networkNumber; newNode.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; this.TreeViewOnUI.Nodes.Add(newNode); return(newNode); }
public DADR(BACnetManager bnm, BACnetPacket.ADDRESS_TYPE adrtyp) { switch (adrtyp) { case BACnetPacket.ADDRESS_TYPE.LOCAL_BROADCAST: isBroadcast = true; isLocalBroadcast = true; viaIPEP = new myIPEndPoint(IPAddress.Broadcast, bnm.insideSocket.ourSocketPort); break; case BACnetPacket.ADDRESS_TYPE.GLOBAL_BROADCAST: this.networkNumber = 0xffff; isBroadcast = true; isLocalBroadcast = false; isRemoteBroadcast = false; MACaddress = new BACnetMACaddress(); break; case BACnetPacket.ADDRESS_TYPE.REMOTE_BROADCAST: isRemoteBroadcast = true; isLocalBroadcast = false; throw new Exception("m0167-A remote broadcast requires an IP address, network number, cannot use this constructor for this"); default: throw new Exception("m0508-Bad parameter"); } }
myTreeNode findTreeNodeDevice(BACnetManager bnm, BACnetPacket pkt) { // Remember, a device is defined by a Network Number and a MAC address. Nothing else! for (int i = 0; i < this.TreeViewOnUI.Nodes.Count; i++) { myTreeNode tnNetwork = (myTreeNode)this.TreeViewOnUI.Nodes[i]; if (tnNetwork.networkNumber == pkt.srcDevice.adr.networkNumber) { // found Network.. now check if node exists for (int j = 0; j < tnNetwork.Nodes.Count; j++) { myTreeNode tnDevice = (myTreeNode)tnNetwork.Nodes[j]; if (tnDevice != null && tnDevice.device != null && tnDevice.device.Equals(pkt.srcDevice)) { // found tnDevice.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; return(tnDevice); } } } } return(null); }
// Returns reference to device node, creating one if necessary. myTreeNode EstablishTreeNodeDevice(BACnetManager bnm, BACnetPacket pkt) { // does one exist? myTreeNode mtnd = findTreeNodeDevice(bnm, pkt); if (mtnd != null) { return(mtnd); } // no, time to create it // establish the network myTreeNode mtnn = EstablishTreeNodeNet(bnm, pkt); myTreeNode newNode = new myTreeNode(); newNode.Text = "Device " + pkt.srcDevice.deviceObjectID.objectInstance; newNode.device.adr = pkt.srcDevice.adr; newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.LastAccessTime, "Seconds since msg 0"); newNode.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; mtnn.Nodes.Add(newNode); // todo, add a few other parameters. mtnn.Expand(); return(newNode); }
public BACnetPacket(AppManager apm, BACnetManager bnm) { lbnm = bnm; _apm = apm; apdu_present = false; npdu.isBroadcast = false; }
// Returns reference to device node, creating one if necessary. myTreeNode EstablishTreeNodeDevice(BACnetManager bnm, BACnetPacket pkt) { // does one exist? myTreeNode mtnd = findTreeNodeDevice(bnm, pkt); if (mtnd != null) { return(mtnd); } // no, time to create it // establish the network myTreeNode mtnn = EstablishTreeNodeNet(bnm, pkt); myTreeNode newNode = new myTreeNode(); // If this is an I-Am-Router-To-Network message, then there is no deviceObject... if (pkt.messageType == BACnetPacket.MESSAGE_TYPE.NETWORK_LAYER) { if (pkt.npdu.function == BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK || pkt.npdu.function == BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_INIT_RT_TABLE_ACK) { // ignore newNode.Text = "Router"; newNode.device.type = BACnetEnums.DEVICE_TYPE.Router; newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.DeviceInstance, ""); newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.MACaddress, ""); newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.VendorID, ""); } else { _apm.MessageTodo("m0140 - What other NPDU only messages could we receive that would want us to create a device?"); } } else { newNode.Text = "Device " + pkt.srcDevice.deviceObjectID.objectInstance; } newNode.device.adr = pkt.srcDevice.adr; //newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.LastAccessTime, "Seconds since msg 0"); newNode.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; mtnn.Nodes.Add(newNode); // todo, add a few other parameters. newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.BACnetADR, pkt.srcDevice.adr.ToString()); mtnn.Expand(); return(newNode); }
public BACnetListener(AppManager apm, BACnetManager bnm, int port) { _bnm = bnm; _apm = apm; BACnet_port = port; _bnm.bacnet_listen_socket = new OurSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp, port); }
public DADR(BACnetManager bnm, BACnetPacket.ADDRESS_TYPE adrtyp, UInt16 networkNumber) { switch (adrtyp) { case BACnetPacket.ADDRESS_TYPE.REMOTE_BROADCAST: isBroadcast = true; viaIPEP = new myIPEndPoint(IPAddress.Broadcast, bnm.insideSocket.ourSocketPort); this.networkNumber = networkNumber; break; case BACnetPacket.ADDRESS_TYPE.LOCAL_BROADCAST: case BACnetPacket.ADDRESS_TYPE.GLOBAL_BROADCAST: throw new Exception("m0169-cannot use this constructor for this"); default: throw new Exception("m0168-Bad parameter"); } }
public bool detect_echo_packet(BACnetManager bnm, BACnetPacket packet) { foreach (IPAddress ipa in bnm.OurIPAddressList) { if (packet.directlyConnectedIPEndPointOfDevice.Address.Equals(ipa)) { // when the sent IP address matches one of ours, check the contents of the packet against the packets stored in the outbound copy queue // // remove all expired packets // foreach (BACnetPacket pkt in outgoing_buffer_copy_queue) // { // if (pkt.timestamp + 5000 < bnm._stopWatch.ElapsedMilliseconds) // { // // drop it // outgoing_buffer_copy_queue.Remove(pkt); // // and quit from this loop, since foreach may fail... // // todo, find a better way to remove all > 5000 ms items // break; // } // } // if (outgoing_buffer_copy_queue.Count > 100) // { // // time to panic // // todo Console.WriteLine("Outbound copy queue overflow"); // outgoing_buffer_copy_queue.Clear(); // return false; // } // if (outgoing_buffer_copy_queue.Contains(packet)) // { // // Console.WriteLine("This message is from ourselves"); // // inform that the packet was a match // return true; // } //} // todo - drop a warning... return(true); } } return(false); }
public void UpdateDeviceTreeView(BACnetManager bnm, BACnetPacket pkt) { if (!pkt.apdu_present) { // means that this packet must be a NPDU message. Treat it differently switch (pkt.npdu.function) { case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK: case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_INIT_RT_TABLE_ACK: // means we had a response from a router - establish the router in our tree. myTreeNode mtnd = EstablishTreeNodeDevice(bnm, pkt); if (mtnd != null) { // found, or established, the treenode matching the device, // now add the objects to it. // update the type of device - we now know it is a router (even if we did not know before). if (mtnd.device != null) { if (mtnd.device.GetType() == typeof(Device)) { // it is still a simple device type, upgrade it _apm.MessageConfigChange(String.Format("m0139 - Device changing from a {0} to a Router", mtnd.Text)); //if (mtnd.router == null) mtnd.router = new Router(mtnd.device); //mtnd.device = null; mtnd.device = new Router(mtnd.device); mtnd.type = myTreeNode.TREENODE_OBJ_TYPE.Router; mtnd.Text = "Router"; } } ((Router)mtnd.device).AddRoutingTableEntries(pkt.routerTableList); // now go through the Router's routing table and display each entry appropriately foreach (RoutingTableEntry rte in ((Router)mtnd.device).routingTableEntries) { bool found = false; for (int i = 0; i < mtnd.Nodes.Count; i++) { if (mtnd.Nodes[i].GetType() == typeof(myTreeNode)) { myTreeNode mtnObj = (myTreeNode)mtnd.Nodes[i]; if (mtnObj.type == myTreeNode.TREENODE_OBJ_TYPE.RouterTableEntry && mtnObj.rte.networkNumber == rte.networkNumber) { // if we get here, the object already exists in the display list and we must not add it again. // but let us check farSide flag for consistency if (mtnObj.rte.farSide != true) { _apm.MessageTodo("m0143-Farside error"); } mtnObj.rte.farSide = true; found = true; // Redo the text, something (like portID) may have been updated mtnObj.Text = rte.ToString(); break; } } } if (!found) { // not found, so add myTreeNode ntn = mtnd.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.RouterTableEntry, rte.ToString()); ntn.rte = rte; ntn.ToolTipText = "Do not right click on this item, it has no effect"; mtnd.Expand(); } } } mtnd.Expand(); break; //case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_INIT_RT_TABLE_ACK: // myTreeNode mtnrt = EstablishTreeNodeDevice(bnm, pkt); // if (mtnrt != null) // { // // found, or established, the treenode matching the device, // // now add the objects to it. // // update the type of device - we now know it is a router (even if we did not know before). // mtnrt.device.type = BACnetEnums.DEVICE_TYPE.Router; // mtnrt.Text = "Router"; // foreach (RoutingTableEntry rp in pkt.routerPortList) // { // bool found = false; // for (int i = 0; i < mtnrt.Nodes.Count; i++) // { // if (mtnrt.Nodes[i].GetType() == typeof(myTreeNode)) // { // myTreeNode mtnObj = (myTreeNode)mtnrt.Nodes[i]; // if (mtnObj.type == myTreeNode.TREENODE_OBJ_TYPE.RouterPort && mtnObj.rp.networkNumber == rp.networkNumber) // { // // if we get here, the object already exists in the list and we must not add it again. // found = true; // // farside nearside stuff mtnObj.networkNumberFromInitRouterTable = true; // // Let us update it though, may be new information // // mtnObj.Text = rp.ToString() ; // break; // } // } // } // if (!found) // { // //// not found, so add // myTreeNode ntn = mtnrt.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.RouterPort, rp.ToString()); // ntn.rp = rp; // // nearside farside stuff ntn.networkNumberFromInitRouterTable = true; // // ntn.ToolTipText = "Do not right click on this item, it has no effect"; // mtnrt.Expand(); // } // } // } // break; } return; } else { // If we reach here, means APDU is present switch (pkt.pduType) { case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: switch (pkt.unconfirmedServiceChoice) { case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM: pkt.srcDevice.directlyConnectedIPEndPointOfDevice = pkt.directlyConnectedIPEndPointOfDevice; // was fromBIP // todo, not sure where I use this - check // bnm.deviceList.Add(pkt.srcDevice); AddDeviceToTreeNode(bnm, pkt); // bnm.newPacketQueue.myEnqueue(packet); break; case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS: // ignore reflected who-is messages break; default: throw new Exception("m0178-Todo"); } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_COMPLEX_ACK: switch (pkt.confirmedServiceChoice) { case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY: myTreeNode mtn; switch (pkt.propertyID) { case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_LIST: // what we need to do here is list the objects on the treeview... // first find the device in the tree mtn = findTreeNodeDevice(bnm, pkt); // add the objects to it if (mtn != null) { // found the treenode matching the device, add the objects to it. foreach (BACnetObjectIdentifier bno in pkt.objectList) { // does it exist? if so, ignore if (findTreeNodeObject(mtn, bno) == null) { // not found, so add myTreeNode ntn = new myTreeNode(); ntn.oID = bno; ntn.type = myTreeNode.TREENODE_OBJ_TYPE.BACnetObject; ntn.Text = bno.objectType.ToString() + " Instance: " + bno.objectInstance.ToString(); ntn.ToolTipText = "Right-click to read more data"; mtn.Nodes.Add(ntn); } } } break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_TYPE: // these properties are of academic interest only. We already have this data from the object list. _apm.MessageTodo("m0080 - Perhaps we need to confirm we have the object on our list already and panic if not"); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_NAME: // Leave these for when we implement stuff on the Browser. // find the device, then the object, then append the name. //mtn = findTreeNodeDevice(bnm, pkt); //myTreeNode mtn2 = findTreeNodeObject(mtn, pkt.objectID); //if (mtn2 == null) //{ // _apm.MessageTodo("m0081 - this is a surprise"); //} //else //{ // mtn2.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.GenericText, "Name"); //} break; default: mtn = findTreeNodeDevice(bnm, pkt); if (mtn != null) { // for now, just add the object. // _apm.MessageTodo("m0524"); //myTreeNode ntn = new myTreeNode(); //ntn.type = myTreeNode.TREENODE_OBJ_TYPE.BACnetObject; //ntn.Text = pkt.propertyID.ToString(); //ntn.ToolTipText = "Do not right click on this item, it has no effect"; //mtn.Nodes.Add(ntn); } break; } break; default: throw new Exception("m0179-Todo"); } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_REJECT: case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_ERROR: // These messages do not affect the Device TreeView, so we will ignore them.. break; default: _apm.MessageTodo("m0027 - Device Treeview needs to parse this message still: " + pkt.pduType.ToString()); break; } } }
void AddDeviceToTreeNode(BACnetManager bnm, BACnetPacket pkt) { // find the network display node, or else add a new one myTreeNode tni = EstablishTreeNodeNet(bnm, pkt); // found Network.. // check if node already exists bool founddeviceflag = false; for (int j = 0; j < tni.Nodes.Count; j++) { myTreeNode tnj = (myTreeNode)tni.Nodes[j]; if (tnj != null && tnj.device.Equals(pkt.srcDevice)) { // found, so quit tnj.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; founddeviceflag = true; tnj.device = pkt.srcDevice; // right here we can update some parameters... (eg. update i-am details from a router...) todonow // newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.BACnetADR, pkt.srcDevice.adr.ToString()); tnj.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.DeviceInstance, pkt.srcDevice.deviceObjectID.objectInstance.ToString()); tnj.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.MACaddress, pkt.srcDevice.adr.MACaddress.ToString()); tnj.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.VendorID, pkt.srcDevice.vendorID.ToString()); tnj.Expand(); break; } } // add a device node to the network node if (founddeviceflag == false) { myTreeNode newNode = new myTreeNode(); newNode.device = pkt.srcDevice; newNode.type = myTreeNode.TREENODE_OBJ_TYPE.Device; newNode.Name = "NewNode"; // todonetxt - add back devicetype //NewNode.Text = "Device " + devUpdate.deviceObjectID.objectInstance + " " + devUpdate.deviceType.ToString(); newNode.Text = "Device "; newNode.ToolTipText = "Right Click on Device Objects for further functionality"; newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.DeviceInstance, pkt.srcDevice.deviceObjectID.objectInstance.ToString()); newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.MACaddress, pkt.srcDevice.adr.MACaddress.ToString()); newNode.UpdatemyTreeNodeLeaf(myTreeNode.TREENODE_OBJ_TYPE.VendorID, pkt.srcDevice.vendorID.ToString()); newNode.Tag = pkt.srcDevice.deviceObjectID.objectInstance; // add other paramters to our new node newNode.lastHeardFromTime = _apm._stopWatch.ElapsedMilliseconds; // todo, need to fix this, since we are adding TreeNodes here, not myTreeNodes... // newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.LastAccessTime, "Seconds since msg 0"); // newNode.Nodes.Add("Seconds since msg 0"); if (pkt.srcDevice.adr.directlyConnected != true) { newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.GenericText, "Router IP Addr " + pkt.srcDevice.directlyConnectedIPEndPointOfDevice); } newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.BACnetADR, "BACnet ADR " + pkt.srcDevice.adr.ToString()); newNode.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.GenericText, "Segmentation " + (int)pkt.srcDevice.SegmentationSupported); // migrated away NewNode.isDevice = true; newNode.Expand(); tni.Nodes.Add(newNode); // tni.ExpandAll(); tni.Expand(); } }
public void UpdateDeviceTreeView(BACnetManager bnm, BACnetPacket pkt) { if (!pkt.apdu_present) { // means that this packet must be a NPDU message. Treat it differently switch (pkt.npdu.function) { case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK: //if (pkt.numberList.Count > 0) //{ // means we had a response from a router - establish the router in our tree. myTreeNode mtnd = EstablishTreeNodeDevice(bnm, pkt); if (mtnd != null) { // found, or established, the treenode matching the device, // now add the objects to it. // update the type of device - we now know it is a router (even if we did not know before). mtnd.device.type = BACnetEnums.DEVICE_TYPE.Router; mtnd.Text = "Router"; if (pkt.numberList != null) { foreach (int bno in pkt.numberList) { bool found = false; for (int i = 0; i < mtnd.Nodes.Count; i++) { if (mtnd.Nodes[i].GetType() == typeof(myTreeNode)) { myTreeNode mtnObj = (myTreeNode)mtnd.Nodes[i]; if (mtnObj.type == myTreeNode.TREENODE_OBJ_TYPE.NetworkNumber && mtnObj.networkNumber == bno) { // if we get here, the object already exists in the list and we must not add it again. mtnObj.networkNumberFromWhoIsRouter = true; found = true; break; } } } if (!found) { //// not found, so add myTreeNode ntn = mtnd.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.NetworkNumber, "Network " + bno.ToString()); ntn.networkNumber = (uint)bno; ntn.networkNumberFromWhoIsRouter = true; ntn.ToolTipText = "Do not right click on this item, it has no effect"; mtnd.Expand(); } } } else { _apm.MessageTodo("m0032"); } } //} break; case BACnetEnums.BACNET_NETWORK_MESSAGE_TYPE.NETWORK_MESSAGE_INIT_RT_TABLE_ACK: myTreeNode mtnrt = EstablishTreeNodeDevice(bnm, pkt); if (mtnrt != null) { // found, or established, the treenode matching the device, // now add the objects to it. // update the type of device - we now know it is a router (even if we did not know before). mtnrt.device.type = BACnetEnums.DEVICE_TYPE.Router; mtnrt.Text = "Router"; foreach (RouterPort rp in pkt.routerPortList) { bool found = false; for (int i = 0; i < mtnrt.Nodes.Count; i++) { if (mtnrt.Nodes[i].GetType() == typeof(myTreeNode)) { myTreeNode mtnObj = (myTreeNode)mtnrt.Nodes[i]; if (mtnObj.type == myTreeNode.TREENODE_OBJ_TYPE.NetworkNumber && mtnObj.networkNumber == rp.networkNumber) { // if we get here, the object already exists in the list and we must not add it again. found = true; mtnObj.networkNumberFromInitRouterTable = true; break; } } } if (!found) { //// not found, so add myTreeNode ntn = mtnrt.AddMyTreeNodeObject(myTreeNode.TREENODE_OBJ_TYPE.NetworkNumber, "Network " + rp.networkNumber.ToString()); ntn.networkNumber = rp.networkNumber; ntn.networkNumberFromInitRouterTable = true; // ntn.ToolTipText = "Do not right click on this item, it has no effect"; mtnrt.Expand(); } } } break; } return; } switch (pkt.pduType) { case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: switch (pkt.unconfirmedServiceChoice) { case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM: pkt.srcDevice.directlyConnectedIPEndPointOfDevice = pkt.directlyConnectedIPEndPointOfDevice; // was fromBIP // todo, not sure where I use this - check bnm.deviceList.Add(pkt.srcDevice); AddDeviceToTreeNode(bnm, pkt); // bnm.newPacketQueue.Enqueue(packet); break; case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS: // ignore reflected who-is messages break; default: BACnetLibraryCL.Panic("Todo"); break; } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_COMPLEX_ACK: switch (pkt.confirmedServiceChoice) { case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY: switch (pkt.propertyID) { case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_LIST: // what we need to do here is list the objects on the treeview... // find the device in the tree // add the objects to it myTreeNode mtn = findTreeNodeDevice(bnm, pkt); if (mtn != null) { // found the treenode matching the device, add the objects to it. if (pkt.objectList != null) { foreach (BACnetObjectIdentifier bno in pkt.objectList) { // does it exist? if so, ignore if (findTreeNodeObject(mtn, bno) == null) { // not found, so add myTreeNode ntn = new myTreeNode(); ntn.oID = bno; ntn.type = myTreeNode.TREENODE_OBJ_TYPE.BACnetObject; ntn.Text = bno.objectType.ToString() + " Instance: " + bno.objectInstance.ToString(); ntn.ToolTipText = "Do not right click on this item, it has no effect"; mtn.Nodes.Add(ntn); } } } // now remove the object list??? (but it will be removed when packet is destroyed.... } break; default: _apm.MessagePanic("m0030 " + pkt.propertyID.ToString()); break; } break; default: _apm.MessagePanic("m0029"); break; } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_REJECT: // These messages do not affect the Device TreeView, so we will ignore them.. break; default: _apm.MessageTodo("m0027 - Device Treeview needs to parse this message still: " + pkt.pduType.ToString()); break; } }
// 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); }
public static void TreeViewUpdate(AppManager apm, BACnetManager bnm, TreeView treeViewMessageLog, bool logmessages) { if (bnm.BACnetMessageLog.Count > 0) { while (bnm.BACnetMessageLog.Count > 0) { // remove the first treenode _count++; PacketLog pktlog = bnm.BACnetMessageLog.Dequeue(); if (!logmessages) { // discard the message, unless it has been logged as an error if (pktlog.BACnetPacket != null && !pktlog.BACnetPacket.errorFlag) { continue; } } TreeNode ntn = new TreeNode(); TreeNodeCollection addBACnetHere = treeViewMessageLog.Nodes; if (pktlog.BACnetPacket != null) { // bump the rest up a level TreeNode nntn = new TreeNode(); nntn.Text = "BACnet"; if (pktlog.sending == true) { nntn.Text = _count.ToString() + " BACnet Sent"; nntn.BackColor = Color.LightPink; } else { nntn.Text = _count.ToString() + " BACnet Recd"; nntn.BackColor = Color.LightGreen; } // display some NPDU parameters if (pktlog.BACnetPacket.npdu.isBroadcast) { nntn.Nodes.Add("To: Broadcast"); } else { if (pktlog.BACnetPacket.dadr != null) { nntn.Nodes.Add("To: " + pktlog.BACnetPacket.dadr.ToString()); } } // From address if (pktlog.BACnetPacket.directlyConnectedIPEndPointOfDevice != null) { nntn.Nodes.Add("From: " + pktlog.BACnetPacket.directlyConnectedIPEndPointOfDevice.ToString()); } if (pktlog.BACnetPacket.npdu.expectingReply) { nntn.Nodes.Add("Expecting Reply"); } if (!pktlog.BACnetPacket.npdu.isNPDUmessage) { switch (pktlog.BACnetPacket.pduType) { case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: nntn.Text += " Unconfirmed Service Request -"; switch (pktlog.BACnetPacket.unconfirmedServiceChoice) { case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM: nntn.Text += " I-Am"; break; case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS: nntn.Text += " Who-Is"; break; default: nntn.Text += " m0019 Unknown BACnet unconfirmed service type - fix line 196 PacketLog.cs"; break; } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_CONFIRMED_SERVICE_REQUEST: nntn.Text += " Confirmed Service Request"; switch (pktlog.BACnetPacket.confirmedServiceChoice) { case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY: nntn.Nodes.Add("Read Property " + pktlog.BACnetPacket.propertyID.ToString()); break; case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROP_MULTIPLE: nntn.Nodes.Add("Read Property Multiple"); break; default: nntn.Nodes.Add("m0014 Unknown BACnet confirmed service type " + pktlog.BACnetPacket.confirmedServiceChoice.ToString()); break; } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_COMPLEX_ACK: nntn.Text += " Complex ACK -"; switch (pktlog.BACnetPacket.confirmedServiceChoice) { case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY: nntn.Text += " Read Property " + pktlog.BACnetPacket.propertyID.ToString(); break; case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROP_MULTIPLE: nntn.Text += " Read Property Multiple"; break; default: nntn.Text += " m0036 Unknown BACnet confirmed service type"; break; } break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_REJECT: nntn.Text += " Reject PDU - " + pktlog.BACnetPacket.pduRejectReason.ToString() + " [" + pktlog.BACnetPacket.invokeID.ToString() + "]"; break; case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_ABORT: apm.MessageTodo("m0092 Resolve pktlog.bacnetpacket.pdutyp " + pktlog.BACnetPacket.pduType.ToString()); break; default: apm.MessageTodo("m0015 Resolve pktlog.bacnetpacket.pdutyp " + pktlog.BACnetPacket.pduType.ToString()); break; } } else if (pktlog.BACnetPacket.apdu_present) { apm.MessageTodo("m0018 I dont expect to see this"); } else { // todo, clean up this flag one day nntn.Nodes.Add("NPDU Function: " + pktlog.BACnetPacket.npdu.function.ToString()); } addBACnetHere.Add(nntn); } treeViewMessageLog.ExpandAll(); // remove all the earlier nodes... while (treeViewMessageLog.Nodes.Count > 150) { treeViewMessageLog.Nodes.RemoveAt(0); } } } }
public static void RespondToAPDU(AppManager apm, BACnetManager bnm, BACnetPacket incomingPacket) { byte[] outbuf = new byte[2000]; int optr; PacketLog pktlog; BACnetPacket outgoingBACpacket = new BACnetPacket(apm, bnm); // fill in some CRP parameters for packet log display outgoingBACpacket.confirmedServiceChoice = incomingPacket.confirmedServiceChoice; outgoingBACpacket.apduConfirmedServiceTypeFlag = incomingPacket.apduConfirmedServiceTypeFlag; outgoingBACpacket.propertyID = incomingPacket.propertyID; outgoingBACpacket.apduUnconfirmedServiceFlag = incomingPacket.apduUnconfirmedServiceFlag; outgoingBACpacket.pduType = incomingPacket.pduType; outgoingBACpacket.unconfirmedServiceChoice = incomingPacket.unconfirmedServiceChoice; outgoingBACpacket.directlyConnectedIPEndPointOfDevice = incomingPacket.directlyConnectedIPEndPointOfDevice; BACnetPacket incomingBACpacket = (BACnetPacket)incomingPacket; if (incomingBACpacket.apduConfirmedServiceTypeFlag == true) { switch (incomingBACpacket.confirmedServiceChoice) { case BACnetEnums.BACNET_CONFIRMED_SERVICE.SERVICE_CONFIRMED_READ_PROPERTY: switch (incomingBACpacket.propertyID) { case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_NAME: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTagString(outbuf, ref optr, apm.ourDeviceName); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); BACnetLibraryCL.InsertContextOpeningTag(outbuf, ref optr, 3); // hardcode the bitstring until we see where else it can be used, then generalized. outbuf[optr++] = 0x83; // Assume length = 3, including unused bits byte // outbuf[optr++] = 0x03; outbuf[optr++] = 0x06; // trailing bits not used InsertBitString(outbuf, optr, 2, (int)BACnetEnums.BACNET_OBJECT_TYPE.OBJECT_DEVICE); optr += 2; BACnetLibraryCL.InsertContextClosingTag(outbuf, ref optr, 3); SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_PROTOCOL_SERVICES_SUPPORTED: optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); BACnetLibraryCL.InsertContextOpeningTag(outbuf, ref optr, 3); //List<BACnetEnums.BACNET_SERVICES_SUPPORTED> servicesList = new List<BACnetEnums.BACNET_SERVICES_SUPPORTED>(); //servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_READ_PROPERTY); //// servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_WRITE_PROPERTY); //servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL); ////servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_REINITIALIZE_DEVICE); //servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_TIME_SYNCHRONIZATION); //servicesList.Add(BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_WHO_IS); //// todo, what about i-am ? //BACnetLibraryCL.InsertApplicationTagString(outbuf, ref optr, servicesList ); // hardcode the bitstring until we see where else it can be used, then generalized. outbuf[optr++] = 0x85; // Assume length = 6 outbuf[optr++] = 0x06; // Length, including the next byte outbuf[optr++] = 0x05; // 5 trailing bits not used InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_READ_PROPERTY); InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL); InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_TIME_SYNCHRONIZATION); InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_WHO_IS); InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_WRITE_PROPERTY); InsertBitString(outbuf, optr, 5, (int)BACnetEnums.BACNET_SERVICES_SUPPORTED.SERVICE_SUPPORTED_REINITIALIZE_DEVICE); optr += 5; BACnetLibraryCL.InsertContextClosingTag(outbuf, ref optr, 3); SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_LIST: // Only respond if array index specified if (!incomingPacket.arrayIndexDecoded) { throw new Exception("m0058 - Not expecting open object list"); } if (incomingPacket.arrayIndex == 0) { optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // arrayIndex 0 InsertContextTag(outbuf, ref optr, 2, 0); // Object count InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTag(outbuf, ref optr, BACnetEnums.BACNET_APPLICATION_TAG.BACNET_APPLICATION_TAG_UNSIGNED_INT, 1); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; // supply the number of objects } else if (incomingPacket.arrayIndex == 1) { // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // arrayIndex 1 InsertContextTag(outbuf, ref optr, 2, 1); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); incomingPacket.objectID.EncodeApplicationTag(outbuf, ref optr); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); } else { throw new Exception("m0059 - Illegal object list index"); } break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_TYPE: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTag(outbuf, ref optr, BACnetEnums.BACNET_APPLICATION_TAG.BACNET_APPLICATION_TAG_ENUMERATED, (uint)BACnetEnums.BACNET_OBJECT_TYPE.OBJECT_DEVICE); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_SYSTEM_STATUS: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTag(outbuf, ref optr, BACnetEnums.BACNET_APPLICATION_TAG.BACNET_APPLICATION_TAG_ENUMERATED, (uint)BACnetEnums.BACNET_DEVICE_STATUS.STATUS_OPERATIONAL); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_OBJECT_IDENTIFIER: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); incomingPacket.objectID.EncodeApplicationTag(outbuf, ref optr); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_VENDOR_NAME: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTagString(outbuf, ref optr, apm.ourVendorName); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_MODEL_NAME: // supply the first (and only) (device) object optr = InsertReadPropertyResponse(apm, incomingBACpacket, outgoingBACpacket, outbuf, incomingBACpacket.propertyID); // Device Object ID InsertContextOpeningTag(outbuf, ref optr, 3); InsertApplicationTagString(outbuf, ref optr, apm.ourModelName); InsertContextClosingTag(outbuf, ref optr, 3); // Send it off SendOffPacket(apm, outgoingBACpacket, outbuf, optr); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_FIRMWARE_REVISION: case BACnetEnums.BACNET_PROPERTY_ID.PROP_APPLICATION_SOFTWARE_VERSION: RespondReadPropertyWithString(apm, incomingBACpacket, outgoingBACpacket, outbuf, apm.ourFirmwareRevision); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_VENDOR_IDENTIFIER: RespondReadPropertyWithUint(apm, incomingBACpacket, outgoingBACpacket, outbuf, apm.ourVendorID); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_PROTOCOL_VERSION: RespondReadPropertyWithUint(apm, incomingBACpacket, outgoingBACpacket, outbuf, 1); break; case BACnetEnums.BACNET_PROPERTY_ID.PROP_PROTOCOL_REVISION: RespondReadPropertyWithUint(apm, incomingBACpacket, outgoingBACpacket, outbuf, 4); break; default: apm.MessageTodo("m0046 - Implement read property " + incomingBACpacket.propertyID.ToString()); break; } break; default: apm.MessageTodo("m0044 - Implement confirmed service " + incomingBACpacket.confirmedServiceChoice.ToString()); break; } } if (incomingBACpacket.apduUnconfirmedServiceFlag == true) { switch (incomingBACpacket.pduType) { case BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: switch (incomingBACpacket.unconfirmedServiceChoice) { case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_WHO_IS: // we need to respond // ONLY if we are in the range, and if not, ignore. if (incomingBACpacket.lowRange != 0 || incomingBACpacket.highRange != 0) { if (apm.ourDeviceId < incomingBACpacket.lowRange || apm.ourDeviceId > incomingBACpacket.highRange) { // This packet not for us apm.MessageLog("m0034 - Ranged Who-Is not addressed to us, ignoring"); break; } } // Compose the response (I-am) outgoingBACpacket.BACnetPort = incomingPacket.BACnetPort; outgoingBACpacket.npdu.isBroadcast = true; outgoingBACpacket.hopcount = 256; // destination address of the BACnet packet. (Must either be b'cast or directlyConnectedIPEP optr = 0; outgoingBACpacket.npdu.isNPDUmessage = false; // makes it an APDU outgoingBACpacket.pduType = BACnetEnums.BACNET_PDU_TYPE.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; outgoingBACpacket.unconfirmedServiceChoice = BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM; outgoingBACpacket.EncodeBACnetNew(outbuf, ref optr); // send the message // if there is no available adapter, this try will throw try { apm.bnm.bacnet_listen_socket.SendTo(outbuf, optr, SocketFlags.None, incomingPacket.directlyConnectedIPEndPointOfDevice); pktlog = new PacketLog(true, incomingPacket.directlyConnectedIPEndPointOfDevice, outgoingBACpacket); pktlog.BACnetPacket = (BACnetPacket)outgoingBACpacket; apm.bnm.BACnetMessageLog.Enqueue(pktlog); } catch (SocketException) { apm.MessageTodo("Either the network cable is unplugged, or there is no configured Ethernet Port on this computer"); } break; case BACnetEnums.BACNET_UNCONFIRMED_SERVICE.SERVICE_UNCONFIRMED_I_AM: break; default: apm.MessageTodo("Implement " + incomingBACpacket.unconfirmedServiceChoice.ToString()); break; } break; default: apm.MessageTodo("Implement " + incomingBACpacket.pduType.ToString()); break; } } }
public BACnetAppTask(AppManager apm, BACnetManager bnm) { _apm = apm; _bnm = bnm; }
public BACnetListener(AppManager apm, BACnetManager bnm) { _apm = apm; this.bnm = bnm; }