/// <summary> /// Sends the specified packet using UDP broadcast to all TCNet devices. /// </summary> /// <param name="packet">The packet to send on the network.</param> protected void Broadcast(Socket socket, TCNetPacket packet) { MemoryStream data = new MemoryStream(); TCNetBinaryWriter writer = new TCNetBinaryWriter(data); IPEndPoint localEndpoint = (IPEndPoint)socket.LocalEndPoint; TCNetHeader header = packet as TCNetHeader; if (header != null) { header.NodeID = NodeId; header.NodeType = Role; header.NodeName = NodeName; header.SequenceNumber = NextSequenceNumber(); header.Timestamp = DateTime.UtcNow.TimeOfDay; } packet.WriteData(writer); try { socket.SendTo(data.ToArray(), new IPEndPoint(BroadcastAddress, localEndpoint.Port)); } catch (SocketException ex) { var broadcastError = new TCNetSocketException(this, "TCNet socket error while broadcasting. See inner exception for more details.", ex); broadcastError.Data["LocalPort"] = localEndpoint.Port; broadcastError.Data["Port"] = localEndpoint.Port; OnUnhandledException(broadcastError); } }
/// <summary> /// Handles the NewPacket event of the TCNetSocket control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="NewPacketEventArgs{TCNetPacket}"/> instance containing the event data.</param> private void TCNetSocket_NewPacket(object sender, NewPacketEventArgs <TCNetPacket> e) { TCNetHeader header = e.Packet as TCNetHeader; DataTypes dataType = DataTypes.None; if (header != null) { TraceEventType traceLevel = TraceEventType.Information; switch (header.MessageType) { case MessageTypes.OptIn: ProcessOptIn(e.Source, (TCNetOptIn)e.Packet); traceLevel = TraceEventType.Verbose; break; case MessageTypes.OptOut: ProcessOptOut((TCNetOptOut)e.Packet); break; case MessageTypes.Time: traceLevel = TraceEventType.Verbose; break; case MessageTypes.Data: { TCNetDataHeader dataHeader = header as TCNetDataHeader; if (dataHeader != null) { dataType = dataHeader.DataType; switch (dataHeader.DataType) { case DataTypes.Metrics: traceLevel = TraceEventType.Verbose; break; } } } break; } tcNetTrace.TraceEvent(traceLevel, (int)header.MessageType, $"{header.NodeName}: {header.GetType().Name} {(dataType != DataTypes.None? dataType.ToString() :string.Empty)}"); } }
/// <summary> /// Sends the specified packet using unicast to a specific DJ Tap device. /// </summary> /// <param name="packet">The packet to send on the network.</param> /// <param name="address">The address of the device to send the packet to.</param> protected void Unicast(TCNetPacket packet, TCNetEndPoint address) { MemoryStream data = new MemoryStream(); TCNetBinaryWriter writer = new TCNetBinaryWriter(data); IPEndPoint localEndpoint = (IPEndPoint)nodeSocket.LocalEndPoint; TCNetHeader header = packet as TCNetHeader; if (header != null) { header.NodeID = NodeId; header.NodeType = Role; header.NodeName = NodeName; header.SequenceNumber = NextSequenceNumber(); header.Timestamp = DateTime.UtcNow.TimeOfDay; TraceEventType traceLevel = TraceEventType.Information; DataTypes dataType = DataTypes.None; TCNetDataHeader dataHeader = header as TCNetDataHeader; if (dataHeader != null) { dataType = dataHeader.DataType; } tcNetTrace.TraceEvent(traceLevel, (int)header.MessageType, $"{header.NodeName}: {header.GetType().Name} {(dataType != DataTypes.None ? dataType.ToString() : string.Empty)}"); } packet.WriteData(writer); try { unicastTXSocket.SendTo(data.ToArray(), new IPEndPoint(address.Address, address.Port)); } catch (SocketException ex) { OnUnhandledException(new TCNetSocketException(this, "Socket error unicast TCNet integration.", ex)); } }
/// <summary> /// Tries to create a packet from the header information. /// </summary> /// <param name="data">The data.</param> /// <param name="timeStamp">The time stamp.</param> /// <param name="packet">The packet.</param> /// <returns></returns> internal static bool TryBuild(TCNetRecieveData data, DateTime timeStamp, out TCNetPacket packet) { TCNetHeader header = new TCNetHeader(MessageTypes.None); packet = header; try { //We have read all the data. if (data.EndOfData()) { data.Reset(); return(false); } //Check we have enough data to construct the header. if (data.Length - data.ReadPosition < TCNetHeader.PacketSize) { return(false); } //Read the packet header. header.ReadData(data.GetReader()); //Ensure the header packet is valid if (!header.IsValid()) { //Purge data as it is probably corrupted. data.Reset(); //Reset position to start so we dump the data. return(false); } //Read the sub packet Func <TCNetPacket> create; switch (header.MessageType) { case MessageTypes.Data: { TCNetDataHeader dataHeader = new TCNetDataHeader(DataTypes.None); //Read the packet header. dataHeader.ReadData(data.GetReader()); if (!registeredDataPackets.TryGetValue(dataHeader.DataType, out create)) { return(false); } } break; case MessageTypes.ApplicationSpecificData: { TCNetApplicationSpecificData dataHeader = new TCNetApplicationSpecificData(); //Read the packet header. dataHeader.ReadData(data.GetReader()); if (!registeredApplicationPackets.TryGetValue(dataHeader.ApplicationSignature, out create)) { return(false); } } break; default: if (!registeredPackets.TryGetValue(header.MessageType, out create)) { return(false); } break; } //Create the sub packet packet = create(); packet.RXTimeStamp = timeStamp; packet.ReadData(data.GetReader()); } catch (EndOfStreamException) { return(false); } return(packet != null); }