/// <summary>
 /// Triggered when a SSDP search result is received
 /// </summary>
 private void UPnPControlPointSearchSink(IPEndPoint source, IPEndPoint local, Uri LocationURL, String USN, String SearchTarget, int MaxAge)
 {
     // A bit like getting a SSDP notification, but we don't do automatic
     // source change in this case. The only valid scenario of a search
     // result is device creation.
     lock (deviceTableLock)
     {
         if (deviceTable.ContainsKey(USN) == false)
         {
             // Never saw this device before
             DeviceInfo deviceInfo = new DeviceInfo();
             deviceInfo.Device     = null;
             deviceInfo.UDN        = USN;
             deviceInfo.NotifyTime = DateTime.Now;
             deviceInfo.BaseURL    = LocationURL;
             deviceInfo.MaxAge     = MaxAge;
             deviceInfo.LocalEP    = local;
             deviceInfo.SourceEP   = source;
             deviceTable[USN]      = deviceInfo;
             deviceFactory.CreateDevice(deviceInfo.BaseURL, deviceInfo.MaxAge, local.Address, USN);
         }
         else
         {
             DeviceInfo deviceInfo = (DeviceInfo)deviceTable[USN];
             if (deviceInfo.Device != null) // If the device is in creation mode, do nothing
             {
                 if (deviceInfo.BaseURL.Equals(LocationURL))
                 {
                     // Cancel a possible source change
                     deviceUpdateClock.Remove(deviceInfo);
                     deviceInfo.PendingBaseURL  = null;
                     deviceInfo.PendingMaxAge   = 0;
                     deviceInfo.PendingLocalEP  = null;
                     deviceInfo.PendingSourceEP = null;
                     // Then simply update the lifetime
                     deviceInfo.NotifyTime = DateTime.Now;
                     deviceTable[USN]      = deviceInfo;
                     deviceLifeTimeClock.Add(deviceInfo.UDN, MaxAge);
                 }
                 else
                 {
                     // Wow, same device, different source - Check timing
                     if (deviceInfo.NotifyTime.AddSeconds(10).Ticks < DateTime.Now.Ticks)
                     {
                         // This is a possible source change. Wait for 3 seconds and make the switch.
                         deviceInfo.PendingBaseURL  = LocationURL;
                         deviceInfo.PendingMaxAge   = MaxAge;
                         deviceInfo.PendingLocalEP  = local;
                         deviceInfo.PendingSourceEP = source;
                         deviceUpdateClock.Add(deviceInfo.UDN, 3);
                     }
                 }
             }
         }
     }
 }
        public void Rescan()
        {
            ArrayList l;

            // We have to copy the list of keys here because we have reports of the hashtable being changed even when the lock is applied;
            lock (deviceTableLock)
            {
                l = new ArrayList(deviceTable.Keys);
            }
            foreach (string USN in l)
            {
                deviceLifeTimeClock.Add(USN, 20);
            }
            genericControlPoint.FindDeviceAsync("upnp:rootdevice");
        }
Пример #3
0
        /// <summary>
        /// Instantiates a new Monitor
        /// </summary>
        /// <param name="onNewInterfaceSink">Interface Callback</param>
        public NetworkInfo(InterfaceHandler onNewInterfaceSink)
        {
            //OpenSource.Utilities.InstanceTracker.Add(this);

            InterfacePoller.OnExpired += new LifeTimeMonitor.LifeTimeHandler(PollInterface);

            NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface i in interfaces)
            {
#if NETSTANDARD
                if (/*i.IsReceiveOnly == false &&*/ i.OperationalStatus == OperationalStatus.Up && i.SupportsMulticast == true)
#else
                if (i.IsReceiveOnly == false && i.OperationalStatus == OperationalStatus.Up && i.SupportsMulticast == true)
#endif
                {
                    IPInterfaceProperties i2 = i.GetIPProperties();
                    foreach (UnicastIPAddressInformation i3 in i2.UnicastAddresses)
                    {
                        if (!AddressTable.Contains(i3.Address) && !i3.Address.Equals(IPAddress.IPv6Loopback))
                        {
                            AddressTable.Add(i3.Address);
                        }
                    }
                }
            }

            /*
             * HostName = Dns.GetHostName();
             * IPHostEntry HostInfo = Dns.GetHostEntry(HostName);
             * AddressTable = new ArrayList(HostInfo.AddressList);
             */

            if (!AddressTable.Contains(IPAddress.Loopback))
            {
                AddressTable.Add(IPAddress.Loopback);
            }

            if (onNewInterfaceSink != null)
            {
                OnNewInterface += onNewInterfaceSink;
                foreach (IPAddress address in AddressTable)
                {
                    OnNewInterfaceEvent.Fire(this, address);
                }
            }

            InterfacePoller.Add(this, NetworkInfo.NetworkPollSeconds);
        }
        /// <summary>
        /// Creates a device from a URL. [Depracated] use UPnPDeviceFactory
        /// </summary>
        /// <param name="DescriptionURL"></param>
        /// <param name="LifeTime"></param>
        public void CreateDeviceAsync(Uri DescriptionURL, int LifeTime)
        {
            //ToDo: Replace the failed callback
            UPnPDeviceFactory fac = new UPnPDeviceFactory(DescriptionURL, LifeTime, new UPnPDeviceFactory.UPnPDeviceHandler(HandleDeviceCreation), null, null, null);

            CreateTable[fac] = fac;
            Lifetime.Add(fac, 30);
        }
        /// <summary>
        /// Instantiates a new MiniWebServer listenting on the given EndPoint
        /// </summary>
        /// <param name="local">IPEndPoint to listen on</param>
        public MiniWebServer(IPEndPoint local)
        {
            OpenSource.Utilities.InstanceTracker.Add(this);

            SessionTimer.OnExpired   += new LifeTimeMonitor.LifeTimeHandler(SessionTimerSink);
            KeepAliveTimer.OnExpired += new LifeTimeMonitor.LifeTimeHandler(KeepAliveSink);
            endpoint_local            = local;

            MainSocket = new Socket(local.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            MainSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
            MainSocket.Bind(local);

            if (MainSocket.LocalEndPoint != null)
            {
                endpoint_local = (IPEndPoint)MainSocket.LocalEndPoint;
            }
            MainSocket.Listen(25);
            MainSocket.BeginAccept(new AsyncCallback(Accept), null);
            KeepAliveTimer.Add(false, 7);
        }
Пример #6
0
        private void HeaderSink(HTTPSession sender, HTTPMessage header, Stream TheStream)
        {
            _Source = sender.Source;
            StateData sd = null;

            if (TheStream != null)
            {
                // This is the result of post-headers in a chunked document
                sd = (StateData)sender.StateObject;
                object Tag = sd.Tag;
                if (sd.HeaderCB != null)
                {
                    sd.HeaderCB(this, sender, header, TheStream, Tag);
                }
                sender.StateObject = null;
                KeepAliveTimer.Add(this.GetHashCode(), 10);
            }
            else
            {
                lock (TagQueue)
                {
                    sd = (StateData)TagQueue.Dequeue();
                }
                sender.StateObject = sd;
                object Tag = sd.Tag;
                if (sd.HeaderCB != null)
                {
                    sd.HeaderCB(this, sender, header, TheStream, Tag);
                    if (sender.UserStream != null && !sender.IsChunked)
                    {
                        // If I don't set this to null, this holds a strong reference, resulting in
                        // possible memory leaks
                        sender.StateObject = null;
                    }
                }
            }
        }
        private void Accept(IAsyncResult result)
        {
            HTTPSession WebSession = null;

            try
            {
                Socket AcceptedSocket = MainSocket.EndAccept(result);
                lock (SessionTable)
                {
                    WebSession               = new HTTPSession(this.LocalIPEndPoint, AcceptedSocket);
                    WebSession.OnClosed     += new HTTPSession.SessionHandler(CloseSink);
                    WebSession.OnHeader     += new HTTPSession.ReceiveHeaderHandler(HandleHeader);
                    WebSession.OnReceive    += new HTTPSession.ReceiveHandler(HandleRequest);
                    SessionTable[WebSession] = WebSession;
                }
                SessionTimer.Add(WebSession, 3);
                OnSessionEvent.Fire(this, WebSession);
                WebSession.StartReading();
            }
            catch (Exception err)
            {
                if (err.GetType() != typeof(System.ObjectDisposedException))
                {
                    // Error
                    OpenSource.Utilities.EventLogger.Log(err);
                }
            }

            try
            {
                MainSocket.BeginAccept(new AsyncCallback(Accept), null);
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                // Socket was closed
            }
        }
Пример #8
0
        private void ProcessPacket(HTTPMessage msg, IPEndPoint src, IPEndPoint local)
        {
            if (OnSniffPacket != null)
            {
                OnSniffPacket(src, null, msg);
            }

            DText parser = new DText();

            parser.ATTRMARK = "::";

            bool   Alive = false;
            String UDN   = msg.GetTag("USN");

            parser[0] = UDN;
            String USN = parser[1];

            USN = USN.Substring(USN.IndexOf(":") + 1);
            String ST     = parser[2];
            int    MaxAge = 0;

            String NTS = msg.GetTag("NTS").ToUpper();

            if (NTS == "SSDP:ALIVE")
            {
                Alive = true;
                String ma = msg.GetTag("Cache-Control").Trim();
                if (ma != "")
                {
                    parser.ATTRMARK = ",";
                    parser.MULTMARK = "=";
                    parser[0]       = ma;
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                        {
                            MaxAge = int.Parse(parser[i, 2].Trim());
                            break;
                        }
                    }
                }
            }

            if (msg.Directive == "NOTIFY" && OnNotify != null)
            {
                Uri    locuri   = null;
                string location = msg.GetTag("Location");
                if (location != null && location.Length > 0)
                {
                    try
                    {
                        locuri = new Uri(location);
                    }
                    catch (Exception ex)
                    {
                        OpenSource.Utilities.EventLogger.Log(ex);
                    }
                }
                OnNotify(src, msg.LocalEndPoint, locuri, Alive, USN, ST, MaxAge, msg);
            }
            else if (msg.Directive == "M-SEARCH" && OnSearch != null)
            {
                if (ValidateSearchPacket(msg) == false)
                {
                    return;
                }
                int          MaxTimer   = int.Parse(msg.GetTag("MX"));
                SearchStruct SearchData = new SearchStruct();
                SearchData.ST     = msg.GetTag("ST");
                SearchData.Source = src;
                SearchData.Local  = local;
                SearchTimer.Add(SearchData, RandomGenerator.Next(0, MaxTimer));
            }
        }