/// <summary>
 /// This instantiates a MiniWebServer if one is not already instantiated
 /// </summary>
 private void CheckMiniWebServer()
 {
     if (MWS == null)
     {
         MWS            = new MiniWebServer(new IPEndPoint(_AVR.device.InterfaceToHost, NetworkInfo.GetFreePort(50000, 65500, _AVR.device.InterfaceToHost)));
         MWS.OnReceive += new MiniWebServer.HTTPReceiveHandler(ReceiveSink);
     }
 }
        public override void Start(UPnPDevice device)
        {
            if (!Enabled)
            {
                return;
            }

            UPnPDevice dv = device;

            while (dv.ParentDevice != null)
            {
                dv = dv.ParentDevice;
            }

            state = UPnPTestStates.Running;
            UPnPService[] _S = device.GetServices("urn:");

            foreach (UPnPService s in _S)
            {
                bool ok = false;
                foreach (UPnPStateVariable v in s.GetStateVariables())
                {
                    if (v.SendEvent)
                    {
                        ok = true;
                        break;
                    }
                }
                if (ok)
                {
                    UPnPDebugObject d        = new UPnPDebugObject(s);
                    Uri             EventUri = new Uri((string)d.GetField("__eventurl"));

                    IPEndPoint  dest = new IPEndPoint(IPAddress.Parse(EventUri.Host), EventUri.Port);
                    HTTPMessage R    = new HTTPMessage();
                    R.Directive    = "SUBSCRIBE";
                    R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                    R.AddTag("Host", dest.ToString());
                    R.AddTag("Callback", "<http://" + dv.InterfaceToHost.ToString() + ":" + NetworkInfo.GetFreePort(10000, 50000, dv.InterfaceToHost).ToString() + ">");
                    //R.AddTag("Callback","<http://127.0.0.1:55555>");
                    R.AddTag("NT", "upnp:event");
                    R.AddTag("Timeout", "Second-15");

                    System.Console.WriteLine(R.GetTag("Callback"));

                    MRE.Reset();
                    SID = "";
                    StartCountDown(30);
                    HTTPRequest rq = new HTTPRequest();
                    rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);

                    AddHTTPMessage(R);

                    rq.PipelineRequest(dest, R, s);
                    MRE.WaitOne(30000, false);
                    AbortCountDown();

                    if (SID == "")
                    {
                        AddEvent(LogImportance.Critical, "Subscribe", "SUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                        AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                        result = "Subscription test failed.";                         // TODO
                        state  = UPnPTestStates.Failed;
                        return;
                    }
                    else
                    {
                        AddEvent(LogImportance.Remark, "Subscribe", "SUBSCRIBE: " + s.ServiceURN + " << OK >>");

                        // Renew Test
                        R              = new HTTPMessage();
                        R.Directive    = "SUBSCRIBE";
                        R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                        R.AddTag("Host", dest.ToString());
                        R.AddTag("SID", SID);
                        R.AddTag("Timeout", "Second-15");
                        StartCountDown(30);
                        SID = "";
                        MRE.Reset();

                        AddHTTPMessage(R);

                        rq             = new HTTPRequest();
                        rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);
                        rq.PipelineRequest(dest, R, s);

                        MRE.WaitOne(30000, false);
                        AbortCountDown();

                        if (SID == "")
                        {
                            AddEvent(LogImportance.Critical, "Subscribe", "SUBSCRIBE (Renew): " + s.ServiceURN + " << FAILED >>");
                            AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                            result = "Subscription test failed.";                             // TODO
                            state  = UPnPTestStates.Failed;
                            return;
                        }
                        else
                        {
                            AddEvent(LogImportance.Remark, "Subscribe", "SUBSCRIBE (Renew): " + s.ServiceURN + " << OK >>");

                            // Cancel
                            R              = new HTTPMessage();
                            R.Directive    = "UNSUBSCRIBE";
                            R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                            R.AddTag("Host", dest.ToString());
                            R.AddTag("SID", SID);

                            StartCountDown(30);
                            SID = "";
                            MRE.Reset();
                            rq             = new HTTPRequest();
                            rq.OnResponse += new HTTPRequest.RequestHandler(CancelSink);

                            AddHTTPMessage(R);

                            rq.PipelineRequest(dest, R, s);

                            MRE.WaitOne(30000, false);
                            AbortCountDown();

                            if (SID == "")
                            {
                                AddEvent(LogImportance.Critical, "Subscribe", "UNSUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                                AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                                result = "Subscription test failed.";
                                state  = UPnPTestStates.Failed;
                                return;
                            }
                            else
                            {
                                AddEvent(LogImportance.Remark, "Subscribe", "UNSUBSCRIBE: " + s.ServiceURN + " << OK >>");
                            }

                            /* Test for duplicate SID
                             * as well as initial events */

                            EventTable.Clear();
                            NumEvents = 0;
                            foreach (UPnPStateVariable V in s.GetStateVariables())
                            {
                                if (V.SendEvent)
                                {
                                    ++NumEvents;
                                    EventTable[V.Name] = false;
                                    V.OnModified      -= new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                    V.OnModified      += new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                }
                            }
                            if (EventTable.Count > 0)
                            {
                                MRE.Reset();
                                s.OnSubscribe -= new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.OnSubscribe += new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.UnSubscribe(null);
                                foreach (UPnPStateVariable V in s.GetStateVariables())
                                {
                                    V.Clear();
                                }
                                s.Subscribe(120, null);
                                MRE.WaitOne(30000, false);
                                if (SID == "")
                                {
                                    // Subscribe Failed
                                    AddEvent(LogImportance.Critical, "Subscribe", "SUBSCRIBE(2): " + s.ServiceURN + " << FAILED >>");
                                    AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                                    result = "Subscription test failed.";
                                    state  = UPnPTestStates.Failed;
                                    return;
                                }
                                else
                                {
                                    if (SID == null)
                                    {
                                        // Duplicate SID
                                        // Subscribe Failed
                                        AddEvent(LogImportance.Critical, "Subscribe", "SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, duplicate SID >>");
                                        AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                                        result = "Subscription test failed.";
                                        state  = UPnPTestStates.Failed;
                                        return;
                                    }
                                    else
                                    {
                                        // Check Hashtable
                                        IDictionaryEnumerator de = EventTable.GetEnumerator();
                                        bool OK = true;
                                        while (de.MoveNext())
                                        {
                                            if ((bool)de.Value == false)
                                            {
                                                // No Event Received
                                                OK = false;
                                                AddEvent(LogImportance.Critical, "Subscribe", "   StateVariable: " + (string)de.Key + " >> Event NOT received");
                                            }
                                            else
                                            {
                                                // OK
                                                AddEvent(LogImportance.Remark, "Subscribe", "   StateVariable: " + (string)de.Key + " >> Event OK");
                                            }
                                        }
                                        if (OK == false)
                                        {
                                            AddEvent(LogImportance.Critical, "Subscribe", "SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, Did not receive all events >>");
                                            AddEvent(LogImportance.Remark, "Subscribe", "Aborting tests");

                                            result = "Subscription test failed.";
                                            state  = UPnPTestStates.Failed;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            result = "Subscribe Tests OK";
            state  = UPnPTestStates.Pass;
        }