예제 #1
0
        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);
        }
예제 #2
0
        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);
        }