internal static DiscoveryMessage CreateFromBytes(byte[] bytes) { GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); DiscoveryMessage result = (DiscoveryMessage)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DiscoveryMessage)); handle.Free(); return(result); }
private void DiscoverRadio() { try { byte[] discoveryMessageBytes = { 0x38, 0x00, 0x5a, 0xa5 }; Array.Resize <byte>(ref discoveryMessageBytes, discoveryMessageBytes[0]); var remoteEndPoint = new IPEndPoint(IPAddress.Broadcast, DISCOVERY_SERVER_PORT); //send discovery message through all interfaces //https://stackoverflow.com/questions/1096142 foreach (var intf in NetworkInterface.GetAllNetworkInterfaces()) { if (intf.OperationalStatus == OperationalStatus.Up && intf.SupportsMulticast && intf.GetIPProperties().GetIPv4Properties() != null && NetworkInterface.LoopbackInterfaceIndex != intf.GetIPProperties().GetIPv4Properties().Index ) { foreach (var addr in intf.GetIPProperties().UnicastAddresses) { if (addr.Address.AddressFamily == AddressFamily.InterNetwork) { var localEndPoint = new IPEndPoint(addr.Address, DISCOVERY_CLIENT_PORT); using (var udpClient = new UdpClient(localEndPoint)) { udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1); udpClient.Send(discoveryMessageBytes, discoveryMessageBytes.Length, remoteEndPoint); } } } } } //receive reply var localEndpoint = new IPEndPoint(IPAddress.Any, DISCOVERY_CLIENT_PORT); using (var udpClient = new UdpClient(localEndpoint)) { udpClient.Client.ReceiveTimeout = 300; var bytes = udpClient.Receive(ref remoteEndPoint); discoveryMessage = DiscoveryMessage.CreateFromBytes(bytes); } //validate reply if (discoveryMessage.Length != DISCOVERY_REPLY_SIZE || discoveryMessage.Key != DISCOVERY_SIGNATURE || discoveryMessage.Op != DISCOVERY_OP_RESP ) { throw (new Exception("invalid reply from the radio")); } if ((discoveryMessage.Status & (STATUS_BIT_CONNECTED | STATUS_BIT_RUNNING)) != 0) { throw (new Exception("radio already in use")); } } catch (Exception e) { throw new Exception($"Afedri SDR not found.\n\n{e.Message}"); } }