private static bool Discovery(ref List <HPSDRDevice> hpsdrdList, IPEndPoint iep, IPAddress targetIP) { // set up HPSDR discovery packet string MAC; byte[] DiscoveryPacketP1 = new byte[63]; Array.Clear(DiscoveryPacketP1, 0, DiscoveryPacketP1.Length); DiscoveryPacketP1[0] = 0xef; DiscoveryPacketP1[1] = 0xfe; DiscoveryPacketP1[2] = 0x02; byte[] DiscoveryPacketP2 = new byte[60]; Array.Clear(DiscoveryPacketP2, 0, DiscoveryPacketP2.Length); DiscoveryPacketP2[4] = 0x02; bool radio_found = false; // true when we find a radio bool static_ip_ok = true; int time_out = 0; // set socket option so that broadcast is allowed. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); // need this so we can Broadcast on the socket IPEndPoint broadcast; // = new IPEndPoint(IPAddress.Broadcast, DiscoveryPort); string receivedIP; // the IP address Metis obtains; assigned, from DHCP or APIPA (169.254.x.y) IPAddress hostPortIPAddress = iep.Address; IPAddress hostPortMask = IPAddress.Broadcast; // find the subnet mask that goes with this host port foreach (NicProperties n in nicProperties) { if (hostPortIPAddress.Equals(n.ipv4Address)) { hostPortMask = n.ipv4Mask; break; } } // send every second until we either find a radio or exceed the number of attempts while (!radio_found) // #### djm should loop for a while in case there are multiple radios { // send a broadcast to port 1024 // try target ip address 1 time if static if (enableStaticIP && static_ip_ok) { broadcast = new IPEndPoint(targetIP, DiscoveryPort); } else { // try directed broadcast address broadcast = new IPEndPoint(IPAddressExtensions.GetBroadcastAddress(hostPortIPAddress, hostPortMask), DiscoveryPort); } if (RadioProtocolSelected == RadioProtocol.Auto || RadioProtocolSelected == RadioProtocol.USB) { socket.SendTo(DiscoveryPacketP1, broadcast); } if (RadioProtocolSelected == RadioProtocol.Auto || RadioProtocolSelected == RadioProtocol.ETH) { socket.SendTo(DiscoveryPacketP2, broadcast); } // now listen on send port for any radio System.Console.WriteLine("Ready to receive.... "); int recv; byte[] data = new byte[100]; bool data_available; // await possibly multiple replies, if there are multiple radios on this port, // which MIGHT be the 'any' port, 0.0.0.0 do { // Poll the port to see if data is available data_available = socket.Poll(100000, SelectMode.SelectRead); // wait 100 msec for time out if (data_available) { EndPoint remoteEP = new IPEndPoint(IPAddress.None, 0); recv = socket.ReceiveFrom(data, ref remoteEP); // recv has number of bytes we received //string stringData = Encoding.ASCII.GetString(data, 0, recv); // use this to print the received data System.Console.WriteLine("RAW Discovery data = " + BitConverter.ToString(data, 0, recv)); // see what port this came from at the remote end // IPEndPoint remoteIpEndPoint = socket.RemoteEndPoint as IPEndPoint; // System.Console.WriteLine(" Remote Port # = ", remoteIpEndPoint.Port); string junk = Convert.ToString(remoteEP); // see code in DataLoop string[] words = junk.Split(':'); System.Console.Write(words[1]); // get MAC address from the payload byte[] mac = { 0, 0, 0, 0, 0, 0 }; Array.Copy(data, 5, mac, 0, 6); MAC = BitConverter.ToString(mac); // check for HPSDR frame ID and type 2 (not currently streaming data, which also means 'not yet in use') // changed to filter a proper discovery packet from the radio, even if already in use! This prevents the need to power-cycle the radio. if (((data[0] == 0xef) && // Protocol-USB (P1) Busy (data[1] == 0xfe) && (data[2] == 0x3)) || ((data[0] == 0x0) && // Protocol-ETH (P2) Busy (data[1] == 0x0) && (data[2] == 0x0) && (data[3] == 0x0) && (data[4] == 0x3))) { System.Console.WriteLine("Radio Busy"); return(false); } if (((data[0] == 0xef) && // Protocol-USB (P1) (data[1] == 0xfe) && (data[2] == 0x2)) || ((data[0] == 0x0) && // Protocol-ETH (P2) (data[1] == 0x0) && (data[2] == 0x0) && (data[3] == 0x0) && (data[4] == 0x2))) { if (data[2] == 0x2) { CurrentRadioProtocol = RadioProtocol.USB; } else { CurrentRadioProtocol = RadioProtocol.ETH; } freqCorrectionChanged(); System.Console.WriteLine("\nFound a radio on the network. Checking whether it qualifies"); // get IP address from the IPEndPoint passed to ReceiveFrom. IPEndPoint ripep = (IPEndPoint)remoteEP; IPAddress receivedIPAddr = ripep.Address; receivedIP = receivedIPAddr.ToString(); IPEndPoint localEndPoint = (IPEndPoint)socket.LocalEndPoint; System.Console.WriteLine("Looking for radio using host adapter IP {0}, port {1}", localEndPoint.Address, localEndPoint.Port); System.Console.WriteLine("IP from IP Header = " + receivedIP); System.Console.WriteLine("MAC address from payload = " + MAC); if (!SameSubnet(receivedIPAddr, hostPortIPAddress, hostPortMask)) { // device is NOT on the subnet that this port actually services. Do NOT add to list! System.Console.WriteLine("Not on subnet of host adapter! Adapter IP {0}, Adapter mask {1}", hostPortIPAddress.ToString(), hostPortMask.ToString()); } else if (MAC.Equals("00-00-00-00-00-00")) { System.Console.WriteLine("Rejected: contains bogus MAC address of all-zeroes"); } else { HPSDRDevice hpsdrd = new HPSDRDevice { IPAddress = receivedIP, MACAddress = MAC, deviceType = CurrentRadioProtocol == RadioProtocol.USB ? (HPSDRHW)data[10] : (HPSDRHW)data[11], codeVersion = CurrentRadioProtocol == RadioProtocol.USB ? data[9] : data[13], hostPortIPAddress = hostPortIPAddress, localPort = localEndPoint.Port, MercuryVersion_0 = data[14], MercuryVersion_1 = data[15], MercuryVersion_2 = data[16], MercuryVersion_3 = data[17], PennyVersion = data[18], MetisVersion = data[19], numRxs = data[20], protocol = CurrentRadioProtocol }; // Map P1 device types to P2 if (CurrentRadioProtocol == RadioProtocol.USB) { switch (data[10]) { case 0: hpsdrd.deviceType = HPSDRHW.Atlas; break; case 1: hpsdrd.deviceType = HPSDRHW.Hermes; break; case 2: hpsdrd.deviceType = HPSDRHW.HermesII; break; case 4: hpsdrd.deviceType = HPSDRHW.Angelia; break; case 5: hpsdrd.deviceType = HPSDRHW.Orion; break; case 10: hpsdrd.deviceType = HPSDRHW.OrionMKII; break; } } if (targetIP != null) { if (hpsdrd.IPAddress.CompareTo(targetIP.ToString()) == 0) { radio_found = true; hpsdrdList.Add(hpsdrd); return(true); } } else { radio_found = true; hpsdrdList.Add(hpsdrd); } } } } else { System.Console.WriteLine("No data from Port = "); if ((++time_out) > 5) { System.Console.WriteLine("Time out!"); return(false); } static_ip_ok = false; } } while (data_available); } return(radio_found); }
public static int initRadio() { int rc; // System.Console.WriteLine("Static IP: " + Console.getConsole().HPSDRNetworkIPAddr); int adapterIndex = adapterSelected - 1; IPAddress[] addr = null; bool cleanup = false; try { addr = Dns.GetHostAddresses(Dns.GetHostName()); } catch (SocketException e) { Win32.WSAData data = new Win32.WSAData(); int result = 0; result = Win32.WSAStartup(VERSION, out data); if (result != IP_SUCCESS) { System.Console.WriteLine(data.description); Win32.WSACleanup(); } addr = Dns.GetHostAddresses(Dns.GetHostName()); cleanup = true; // System.Console.WriteLine("SocketException caught!!!"); // System.Console.WriteLine("Source : " + e.Source); // System.Console.WriteLine("Message : " + e.Message); } catch (Exception e) { System.Console.WriteLine("Exception caught!!!"); System.Console.WriteLine("Source : " + e.Source); System.Console.WriteLine("Message : " + e.Message); } GetNetworkInterfaces(); List <IPAddress> addrList = new List <IPAddress>(); // make a list of all the adapters that we found in Dns.GetHostEntry(strHostName).AddressList foreach (IPAddress a in addr) { // make sure to get only IPV4 addresses! // test added because Erik Anderson noted an issue on Windows 7. May have been in the socket // construction or binding below. if (a.AddressFamily == AddressFamily.InterNetwork) { addrList.Add(a); } } bool foundRadio = false; List <HPSDRDevice> hpsdrd = new List <HPSDRDevice>(); if (enableStaticIP) { HpSdrHwIpAddress = Console.getConsole().HPSDRNetworkIPAddr; IPAddress remoteIp = IPAddress.Parse(HpSdrHwIpAddress); IPEndPoint remoteEndPoint = new IPEndPoint(remoteIp, 0); Socket sock = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint localEndPoint = QueryRoutingInterface(sock, remoteEndPoint); EthernetHostIPAddress = IPAddress.Parse(localEndPoint.Address.ToString()).ToString(); sock.Close(); sock = null; // if success set foundRadio to true, and fill in ONE hpsdrd entry. IPAddress targetIP; IPAddress hostIP; if (IPAddress.TryParse(EthernetHostIPAddress, out hostIP) && IPAddress.TryParse(HpSdrHwIpAddress, out targetIP)) { System.Console.WriteLine(String.Format("Attempting connect to host adapter {0}, Static IP {1}", EthernetHostIPAddress, HpSdrHwIpAddress)); if (DiscoverRadioOnPort(ref hpsdrd, hostIP, targetIP)) { foundRadio = true; // make sure that there is only one entry in the list! if (hpsdrd.Count > 0) { // remove the extra ones that don't match! HPSDRDevice m2 = null; foreach (var m in hpsdrd) { if (m.IPAddress.CompareTo(HpSdrHwIpAddress) == 0) { m2 = m; } } // clear the list and put our single element in it, if we found it. hpsdrd.Clear(); if (m2 != null) { hpsdrd.Add(m2); } else { foundRadio = false; } } } } } if (FastConnect && (EthernetHostIPAddress.Length > 0) && (HpSdrHwIpAddress.Length > 0)) { // if success set foundRadio to true, and fill in ONE hpsdrd entry. IPAddress targetIP; IPAddress hostIP; if (IPAddress.TryParse(EthernetHostIPAddress, out hostIP) && IPAddress.TryParse(HpSdrHwIpAddress, out targetIP)) { System.Console.WriteLine(String.Format("Attempting fast re-connect to host adapter {0}, IP {1}", EthernetHostIPAddress, HpSdrHwIpAddress)); if (DiscoverRadioOnPort(ref hpsdrd, hostIP, targetIP)) { foundRadio = true; // make sure that there is only one entry in the list! if (hpsdrd.Count > 0) { // remove the extra ones that don't match! HPSDRDevice m2 = null; foreach (var m in hpsdrd) { if (m.IPAddress.CompareTo(HpSdrHwIpAddress) == 0) { m2 = m; } } // clear the list and put our single element in it, if we found it. hpsdrd.Clear(); if (m2 != null) { hpsdrd.Add(m2); } else { foundRadio = false; } } } } } if (!foundRadio) { foreach (IPAddress ipa in addrList) { if (DiscoverRadioOnPort(ref hpsdrd, ipa, null)) { foundRadio = true; } } } if (!foundRadio) { if (cleanup) { Win32.WSACleanup(); } return(-1); } int chosenDevice = 0; BoardID = hpsdrd[chosenDevice].deviceType; FWCodeVersion = hpsdrd[chosenDevice].codeVersion; HpSdrHwIpAddress = hpsdrd[chosenDevice].IPAddress; HpSdrHwMacAddress = hpsdrd[chosenDevice].MACAddress; EthernetHostIPAddress = hpsdrd[chosenDevice].hostPortIPAddress.ToString(); EthernetHostPort = hpsdrd[chosenDevice].localPort; NumRxs = hpsdrd[chosenDevice].numRxs; if (BoardID == HPSDRHW.HermesII) { if (FWCodeVersion < 103) { fwVersionMsg = "Invalid Firmware!\nRequires 10.3 or greater. "; return(-101); } } rc = nativeInitMetis(HpSdrHwIpAddress, EthernetHostIPAddress, EthernetHostPort, (int)CurrentRadioProtocol); return(-rc); }