public int Send(byte[] buffer, int offset, int data_length, BacnetAddress address, bool wait_for_transmission, int timeout) { if (m_TS == -1) { throw new Exception("Source address must be set up before sending messages"); } //add to queue BacnetNpduControls function = NPDU.DecodeFunction(buffer, offset); BacnetMstpFrameTypes frame_type = (function & BacnetNpduControls.ExpectingReply) == BacnetNpduControls.ExpectingReply ? BacnetMstpFrameTypes.FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY : BacnetMstpFrameTypes.FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; byte[] copy = new byte[data_length + MSTP.MSTP_HEADER_LENGTH + 2]; Array.Copy(buffer, offset, copy, MSTP.MSTP_HEADER_LENGTH, data_length); MessageFrame f = new MessageFrame(frame_type, address.adr[0], copy, data_length); lock (m_send_queue) m_send_queue.AddLast(f); if (m_reply == null) { m_reply = f; m_reply_mutex.Set(); } //wait for message to be sent if (wait_for_transmission) { if (!f.send_mutex.WaitOne(timeout)) { return(-ETIMEDOUT); } } return(data_length); }
public static void Encode(EncodeBuffer buffer, BacnetNpduControls function, BacnetAddress destination, BacnetAddress source = null, byte hopCount = 0xFF) { // Modif FC var hasDestination = destination != null && destination.net > 0; // && destination.net != 0xFFFF; var hasSource = source != null && source.net > 0 && source.net != 0xFFFF; buffer.buffer[buffer.offset++] = BACNET_PROTOCOL_VERSION; buffer.buffer[buffer.offset++] = (byte)(function | (hasDestination ? BacnetNpduControls.DestinationSpecified : 0) | (hasSource ? BacnetNpduControls.SourceSpecified : 0)); if (hasDestination) { buffer.buffer[buffer.offset++] = (byte)((destination.net & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((destination.net & 0x00FF) >> 0); if (destination.net == 0xFFFF) //patch by F. Chaxel { buffer.buffer[buffer.offset++] = 0; } else { buffer.buffer[buffer.offset++] = (byte)destination.adr.Length; if (destination.adr.Length > 0) { foreach (var t in destination.adr) { buffer.buffer[buffer.offset++] = t; } } } } if (hasSource) { buffer.buffer[buffer.offset++] = (byte)((source.net & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((source.net & 0x00FF) >> 0); // Modif FC if (destination.net == 0xFFFF) { buffer.buffer[buffer.offset++] = 0; } else { buffer.buffer[buffer.offset++] = (byte)destination.adr.Length; if (destination.adr.Length > 0) { foreach (var t in destination.adr) { buffer.buffer[buffer.offset++] = t; } } } } if (hasDestination) { buffer.buffer[buffer.offset++] = hopCount; } }
public static void Encode(EncodeBuffer buffer, BacnetNpduControls function, BacnetAddress destination, BacnetAddress source, byte hopCount, BacnetNetworkMessageTypes networkMsgType, ushort vendorId) { Encode(buffer, function, destination, source, hopCount); if (function.HasFlag(BacnetNpduControls.NetworkLayerMessage)) // sure it is, otherwise the other Encode is used { buffer.buffer[buffer.offset++] = (byte)networkMsgType; if ((byte)networkMsgType >= 0x80) // who used this ??? sure nobody ! { buffer.buffer[buffer.offset++] = (byte)((vendorId & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((vendorId & 0x00FF) >> 0); } } }
public static int Decode(byte[] buffer, int offset, out BacnetNpduControls function, out BacnetAddress destination, out BacnetAddress source, out byte hopCount, out BacnetNetworkMessageTypes networkMsgType, out ushort vendorId) { var orgOffset = offset; offset++; function = (BacnetNpduControls)buffer[offset++]; destination = null; if ((function & BacnetNpduControls.DestinationSpecified) == BacnetNpduControls.DestinationSpecified) { destination = new BacnetAddress(BacnetAddressTypes.None, (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0)), null); int adrLen = buffer[offset++]; if (adrLen > 0) { destination.adr = new byte[adrLen]; for (var i = 0; i < destination.adr.Length; i++) { destination.adr[i] = buffer[offset++]; } } } source = null; if ((function & BacnetNpduControls.SourceSpecified) == BacnetNpduControls.SourceSpecified) { source = new BacnetAddress(BacnetAddressTypes.None, (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0)), null); int adrLen = buffer[offset++]; if (adrLen > 0) { source.adr = new byte[adrLen]; for (var i = 0; i < source.adr.Length; i++) { source.adr[i] = buffer[offset++]; } } } hopCount = 0; if ((function & BacnetNpduControls.DestinationSpecified) == BacnetNpduControls.DestinationSpecified) { hopCount = buffer[offset++]; } networkMsgType = BacnetNetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK; vendorId = 0; if (function.HasFlag(BacnetNpduControls.NetworkLayerMessage)) { networkMsgType = (BacnetNetworkMessageTypes)buffer[offset++]; if ((byte)networkMsgType >= 0x80) { vendorId = (ushort)((buffer[offset++] << 8) | (buffer[offset++] << 0)); } else if (networkMsgType == BacnetNetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK) { offset += 2; // Don't care about destination network adress } } if (buffer[orgOffset + 0] != BACNET_PROTOCOL_VERSION) { return(-1); } return(offset - orgOffset); }
public static void Encode(EncodeBuffer buffer, BacnetNpduControls function, BacnetAddress destination, BacnetAddress source, byte hop_count, BacnetNetworkMessageTypes network_msg_type, ushort vendor_id) { // Modif FC bool has_destination = destination != null && destination.net > 0; // && destination.net != 0xFFFF; bool has_source = source != null && source.net > 0 && source.net != 0xFFFF; buffer.buffer[buffer.offset++] = BACNET_PROTOCOL_VERSION; buffer.buffer[buffer.offset++] = (byte)(function | (has_destination ? BacnetNpduControls.DestinationSpecified : 0) | (has_source ? BacnetNpduControls.SourceSpecified : 0)); if (has_destination) { buffer.buffer[buffer.offset++] = (byte)((destination.net & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((destination.net & 0x00FF) >> 0); if (destination.net == 0xFFFF) //patch by F. Chaxel { buffer.buffer[buffer.offset++] = 0; } else { buffer.buffer[buffer.offset++] = (byte)destination.adr.Length; if (destination.adr.Length > 0) { for (int i = 0; i < destination.adr.Length; i++) { buffer.buffer[buffer.offset++] = destination.adr[i]; } } } } if (has_source) { buffer.buffer[buffer.offset++] = (byte)((source.net & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((source.net & 0x00FF) >> 0); // Modif FC if (destination.net == 0xFFFF) { buffer.buffer[buffer.offset++] = 0; } else { buffer.buffer[buffer.offset++] = (byte)destination.adr.Length; if (destination.adr.Length > 0) { for (int i = 0; i < destination.adr.Length; i++) { buffer.buffer[buffer.offset++] = destination.adr[i]; } } } } if (has_destination) { buffer.buffer[buffer.offset++] = hop_count; } /* * //display warning * if (has_destination || has_source) * { * System.Diagnostics.Trace.TraceWarning("NPDU size is more than 4. This will give an error in the current max_apdu calculation"); * } */ if ((function & BacnetNpduControls.NetworkLayerMessage) > 0) { buffer.buffer[buffer.offset++] = (byte)network_msg_type; if (((byte)network_msg_type) >= 0x80) { buffer.buffer[buffer.offset++] = (byte)((vendor_id & 0xFF00) >> 8); buffer.buffer[buffer.offset++] = (byte)((vendor_id & 0x00FF) >> 0); } } }