/// <summary> /// Deserializes the message from a buffer /// </summary> /// <param name="buffer">The buffer to deserialize from</param> /// <param name="offset">The offset to begin deserializing</param> /// <returns>The offset of the next byte in the buffer</returns> public int Deserialize(byte[] buffer, int offset) { byte[] bytes = new byte[6]; for (int i = 0; i < bytes.Length; i++) { bytes[i] = buffer[offset++]; } this.OriginalMac = new Mac(bytes, false); return offset; }
/// <summary> /// Sends a bvlc message /// </summary> /// <param name="mac">The BACnet mac address of the destination device</param> /// <param name="message"></param> private void _sendMessage(Mac mac, IBvlcMessage message) { // TODO: constant for buffer size, or // lease buffers from the UDPAsyncServer instance IPEndPoint ep = IPUtils.MacToIPEndPoint(mac); byte[] buffer = new byte[1500]; int offset = 0; BvlcHeader header = null; header = new BvlcHeader(); header.Function = message.Function; header.Length = 0; offset = header.Serialize(buffer, offset); offset = message.Serialize(buffer, offset); // patch the length in now that it is known buffer[2] = (byte)(offset << 8); buffer[3] = (byte)(offset); _server.Send(ep, buffer, offset); }
public NetgramReceivedMessage(byte portId, Mac source, BufferSegment segment) { this.PortId = portId; this.Source = source; this.Segment = segment; }
/// <summary> /// Processes a received bvlc message /// </summary> /// <param name="mac">The mac address of the device that sent the message</param> /// <param name="message">The bvlc message</param> /// <param name="buffer">The buffer containing the message content</param> /// <param name="offset">The offset of the content within the message</param> /// <param name="length">The length of the received datagram</param> /// <returns>The inbound netgram to propagate, if any</returns> private NetgramReceivedMessage _processMessage(Mac mac, IBvlcMessage message, byte[] buffer, int offset, int length) { switch(message.Function) { case FunctionCode.Result: _processResult(mac, ((ResultMessage)message).Result); break; case FunctionCode.ForwardedNpdu: mac = ((ForwardedNpduMessage)message).OriginalMac; goto case FunctionCode.OriginalUnicastNpdu; case FunctionCode.OriginalUnicastNpdu: case FunctionCode.OriginalBroadcastNpdu: return _createInboundNetgram(mac, buffer, offset, length); } return null; }
/// <summary> /// Processes a received result message /// </summary> /// <param name="mac">The mac address of the device that sent the message</param> /// <param name="code">The result code of the message</param> private void _processResult(Mac mac, ResultCode code) { // we only process certain results from the BBMD if (mac == _bbmdMac) { if(code == ResultCode.Success && (_state == State.Registering || _state == State.Renewing)) { Console.WriteLine("Register Success"); _state = State.Open; _registrationTimeout = DateTime.UtcNow.Add(_options.RegistrationInterval); } } }
/// <summary> /// Creates the bbmd mac address /// </summary> private void _createBbmdMac() { var bbmdIps = Dns.GetHostAddresses(_options.BbmdHost); if (bbmdIps.Length == 0) { throw new Exception("Could not resolve '" + _options.BbmdHost + "'"); } var bbmdEp = new IPEndPoint(bbmdIps[0], _options.BbmdPort); _bbmdMac = IPUtils.IPEndPointToMac(bbmdEp); }
/// <summary> /// Creates an inbound netgram /// </summary> /// <param name="mac">The mac address of the device that sent the netgram</param> /// <param name="buffer">The buffer containing the netgram content</param> /// <param name="offset">The offset of the netgram within the buffer</param> /// <param name="length">The length of the received datagram</param> private NetgramReceivedMessage _createInboundNetgram(Mac mac, byte[] buffer, int offset, int length) { return new NetgramReceivedMessage( this.PortId, mac, new BufferSegment(buffer, offset, length)); }
/// <summary> /// Constructs a new address instance /// </summary> /// <param name="network">The network number of the address</param> /// <param name="mac">The mac address of the address</param> public Address(ushort network, Mac mac) { this.Network = network; this.Mac = mac; }
/// <summary> /// Called whenever a packet is captured on the capture device /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event args</param> private void _onPacketArrival(object sender, CaptureEventArgs e) { // don't process any packet too short to not be valid if (e.Packet.Data.Length < _minimumPacketLength) return; // don't process any packets sent by the local device if (_isOutboundPacket(e.Packet.Data)) return; byte[] buffer = e.Packet.Data; int offset = 0; Mac destination, source; int length; byte dsap, ssap, control; destination = new Mac(buffer, offset, 6); offset += 6; source = new Mac(buffer, offset, 6); offset += 6; length = buffer.ReadUInt16(offset); offset += 2; dsap = buffer[offset++]; ssap = buffer[offset++]; control = buffer[offset++]; // don't process non-BACnet packets if (dsap != 0x82 || ssap != 0x82 || control != 0x03) return; NetgramReceivedMessage message = new NetgramReceivedMessage( this.PortId, source, new BufferSegment(buffer, offset, buffer.Length)); if (Session != null) { Session.QueueMessage(message); } }
/// <summary> /// Adds a new remote route to routing table /// </summary> /// <param name="network">The network number of the route</param> /// <param name="portId">The port id of the route</param> /// <param name="nextHop">The next hop mac address</param> public Route AddRemoteRoute(ushort network, byte portId, Mac nextHop) { int index = _findRoute(network); return _upsertRoute(index, new Route(network, portId, nextHop)); }
/// <summary> /// Constructs a new Route instance /// </summary> /// <param name="network">The network number of the route</param> /// <param name="portId">The port id of the next hop port</param> /// <param name="nextHop">The next hop mac address, or a broadcast address for a local port</param> public Route(ushort network, byte portId, Mac nextHop) { this.Network = network; this.PortId = portId; this.NextHop = nextHop; }