public override string Event(MiniWebServer.Request request, int service_index)
 {
     if (service_index >= root_device.Services.Count)
         return ("");//TODO put a real error message in here
     //TODO change to void method and send request answer inline
     //TODO maybe remove request parameter and change to soap_action + body strings
     return ("");
 }
            public override string Control(MiniWebServer.Request request, int service_index)
            {
                if (service_index >= root_device.Services.Count)
                    return ("");//TODO put a real error message in here
                SubDevice.Service control_service = root_device.Services[service_index];
                //Console.WriteLine("opened control url of service :" + control_service.ServiceType);
                //Console.WriteLine("body:" + request.Body);
                //Console.WriteLine("soap action:" + request.Headers.Get("SOAPACTION"));
                char[] trims = { '"'};
                if (request.Headers.Get("SOAPACTION").Trim().Trim(trims) == "urn:schemas-upnp-org:service:ContentDirectory:1#Browse")
                {
                    string soap_answer = "";
                    soap_answer += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
                    soap_answer += "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
                    soap_answer += "<s:Body>";
                    soap_answer += "<u:Browse xmlns:u=\"urn:" + control_service.ServiceType + "\">";
                    //soap_answer += "<ObjectID>0</ObjectID>";
                    //soap_answer += "<BrowseFlag>BrowseDirectChildren</BrowseFlag>";
                    //soap_answer += "<Filter>*</Filter>";
                    //soap_answer += "<StartingIndex>0</StartingIndex>";
                    //soap_answer += "<RequestedCount>10</RequestedCount>";
                    //soap_answer += "<SortCriteria />";
                    //input values
                    string object_id = UPnP.GetStringInbetween(request.Body, "<ObjectID>", "</ObjectID>");
                    string browse_flag = UPnP.GetStringInbetween(request.Body, "<BrowseFlag>", "</BrowseFlag>");
                    string filter = UPnP.GetStringInbetween(request.Body, "<Filter>", "</Filter>");
                    int starting_index = UPnP.GetIntInbetween(request.Body, "<StartingIndex>", "</StartingIndex>");
                    int requested_count = UPnP.GetIntInbetween(request.Body, "<RequestedCount>", "</RequestedCount>");
                    string sort_criteria = UPnP.GetStringInbetween(request.Body, "<SortCriteria>", "</SortCriteria>");
                    if (starting_index == -1)
                        starting_index = 0;
                    if (requested_count == -1)
                        requested_count = 0;
                    //output values
                    string didl = "";
                    int total_matches = 0;
                    int number_returned = 0;
                    int update_id = 0;

                    if (BrowseRequestReceived != null)
                    {
                        BrowseResult result = new BrowseResult();
                        result = BrowseRequestReceived(this, object_id, browse_flag, starting_index, requested_count, sort_criteria);
                        if (result.AutoIndex)
                        {
                            total_matches = result.NumberReturned;
                            didl = result.GetIndexedDidl(starting_index, requested_count);
                        }
                        else
                        {
                            didl = result.Didl;
                            total_matches = result.TotalMatches;
                        }
                        didl = XmlStrings.ToXmlString(didl);
                        number_returned = result.NumberReturned;
                        update_id = result.UpdateID;
                    }

                    soap_answer += "<Result>" + didl + "</Result>";
                    soap_answer += "<NumberReturned>" + number_returned + "</NumberReturned>";
                    soap_answer += "<TotalMatches>" + total_matches + "</TotalMatches>";
                    soap_answer += "<UpdateID>" + update_id + "</UpdateID>";
                    soap_answer += "</u:Browse>";
                    soap_answer += "</s:Body>";
                    soap_answer += "</s:Envelope>";
                    return (soap_answer);
                }
                //TODO add a real soap error response here
                return("");
            }
            public override string Description(MiniWebServer.Request request, int service_index)
            {
                if (service_index >= root_device.Services.Count)
                    return ("");//TODO put a real error message in here
                string ret = "";
                if (root_device.Services[service_index].ServiceType == "schemas-upnp-org:service:ConnectionManager:1")
                {
                    try
                    {
                        ret = File.ReadAllText(".\\web\\ConnectionManager.scpd");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error reading service description file: " + ex.Message);
                    }
                }
                else if (root_device.Services[service_index].ServiceType == "schemas-upnp-org:service:ContentDirectory:1")
                {
                    try
                    {
                        ret = File.ReadAllText(".\\web\\ContentDirectory.scpd");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error reading service description file: " + ex.Message);
                    }

                }
                return (ret);
            }
 public abstract string Description(MiniWebServer.Request request, int service_index);
 public abstract string Event(MiniWebServer.Request request, int service_index);
 /// <summary>
 /// stops the mini web server to handle local device requests
 /// if running
 /// </summary>
 private void StopLocalDeviceHandler()
 {
     lock (local_device_handler_started_lock)
     {
         if (local_device_handler_started)
         {
             local_device_handler_started = false;
             local_device_handler.CloseListeningSocket();
             local_device_handler = null;
         }
     }
 }
 public abstract string Control(MiniWebServer.Request request, int service_index);
        /// <summary>
        /// starts the mini web server to handle local device requests
        /// if not already running
        /// </summary>
        private void StartLocalDeviceHandler()
        {
            lock (local_device_handler_started_lock)
            {
                if (!local_device_handler_started)
                {
                    local_device_handler_started = true;

                    //local_device_timer = new System.Timers.Timer((max_age - 5) * 1000);
                    local_device_timer = new System.Timers.Timer(local_device_timer_interval * 1000); //check every 5 seconds if an announcement needs to be made
                    local_device_timer.AutoReset = true;
                    local_device_timer.Elapsed += delegate(object sender, ElapsedEventArgs e)
                    {
                        AnnouncementTimerCheck();
                    };
                    local_device_timer.Start();

                    local_device_handler = new MiniWebServer();
                    local_device_handler.SetupListeningSocket();
                    local_device_handler.RequestReceived += delegate(MiniWebServer request_server, MiniWebServer.Request request)
                        {

                            int device_id = -1;
                            string device_id_string = "-1";
                            int device_id_start = request.Url.IndexOf("/device/");
                            if (device_id_start != -1)
                            {
                                device_id_string = request.Url.Substring(device_id_start + "/device/".Length);
                                int device_id_end = device_id_string.IndexOf("/");
                                if (device_id_end != -1)
                                {
                                    device_id_string = device_id_string.Substring(0, device_id_end);
                                    //Console.WriteLine("device id string: " + device_id_string);
                                }
                            }
                            try
                            {
                                device_id = int.Parse(device_id_string);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("error parsing device id: " + ex.Message);
                            }

                            int service_id = -1;
                            string service_id_string = "-1";
                            int service_id_start = request.Url.IndexOf("/service/");
                            if (service_id_start != -1)
                            {
                                service_id_string = request.Url.Substring(service_id_start + "/service/".Length);
                                int service_id_end = service_id_string.IndexOf("/");
                                if (service_id_end != -1)
                                {
                                    service_id_string = service_id_string.Substring(0, service_id_end);
                                    //Console.WriteLine("service id string: " + service_id_string);
                                }
                            }

                            try
                            {
                                service_id = int.Parse(service_id_string);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("error parsing service id: " + ex.Message);
                            }

                            if (device_id != -1)
                            {
                                //if (device_id >= local_devices.Count)
                                //    request.RequestClient.TellNotFound();
                                LocalDevice device = GetLocalDeviceByDeviceID(device_id);
                                if (device == null)
                                {
                                    Console.WriteLine("Device in url (" + device_id + ") not found.");
                                    request.RequestClient.TellNotFound();
                                    return;
                                }

                                if (service_id != -1)
                                {
                                    if (service_id >= device.RootDevice.Services.Count)
                                    {
                                        request.RequestClient.TellNotFound();
                                        return;
                                    }
                                    if (request.Url.EndsWith("/scpd.xml"))
                                    {
                                        //TODO add correct scpd of service in here
                                        //Console.WriteLine("Clients want the service description xml. -> oops ;-)");
                                        SubDevice.Service control_service = device.RootDevice.Services[service_id];
                                        //Console.WriteLine("opened description url of service :" + control_service.ServiceType);
                                        request.RequestClient.Answer(device.Description(request, service_id), "text/xml");
                                    }
                                    else if (request.Url.EndsWith("/control"))
                                    {
                                        request.RequestClient.Answer(device.Control(request, service_id), "text/xml");
                                    }
                                    else if (request.Url.EndsWith("/event"))
                                    {
                                        SubDevice.Service control_service = device.RootDevice.Services[service_id];
                                        //SubDevice.Service control_service = local_devices[device_id].RootDevice.GetServiceByID(service_id);
                                        //Console.WriteLine("opened event url of service :" + control_service.ServiceType);
                                        request.RequestClient.Answer(device.Event(request, service_id), "text/xml");
                                    }
                                }
                                else if (request.Url.EndsWith("/root.xml"))
                                {
                                    string root_description = "";
                                    root_description += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
                                    root_description += "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">";
                                    root_description += "<specVersion>";
                                    root_description += "<major>" + device.SpecVersionMajor + "</major>";
                                    root_description += "<minor>" + device.SpecVersionMinor + "</minor>";
                                    root_description += "</specVersion>";
                                    root_description += "<device>";
                                    root_description += "<deviceType>urn:" + device.RootDevice.DeviceType + "</deviceType>";
                                    //root_description += "<INMPR03>1.0</INMPR03>";
                                    root_description += "<friendlyName>" + device.RootDevice.FriendlyName + "</friendlyName>";
                                    root_description += "<manufacturer>" + device.RootDevice.Manufacturer + "</manufacturer>";
                                    root_description += "<manufacturerURL>" + device.RootDevice.ManufacturerUrl + "</manufacturerURL>";
                                    root_description += "<modelDescription>" + device.RootDevice.ModelDescription + "</modelDescription>";
                                    root_description += "<modelName>" + device.RootDevice.ModelName + "</modelName>";
                                    root_description += "<modelNumber>" + device.RootDevice.ModelNumber + "</modelNumber>";
                                    root_description += "<modelURL>" + device.RootDevice.ModelUrl + "</modelURL>";
                                    root_description += "<UDN>uuid:" + device.RootDevice.UniversalUniqueID + "</UDN>";
                                    root_description += "<serviceList>";
                                    int service_index = 0;
                                    foreach (SubDevice.Service service in device.RootDevice.Services)
                                    {
                                        root_description += "<service>";
                                        root_description += "<serviceType>urn:" + service.ServiceType + "</serviceType>";
                                        root_description += "<serviceId>urn:" + service.ServiceID + "</serviceId>";
                                        root_description += "<SCPDURL>/device/" + device.DeviceID + "/service/" + service_index + "/scpd.xml</SCPDURL>";
                                        root_description += "<controlURL>/device/" + device.DeviceID + "/service/" + service_index + "/control</controlURL>";
                                        root_description += "<eventSubURL>/device/" + device.DeviceID + "/service/" + service_index + "/event</eventSubURL>";
                                        root_description += "</service>";
                                        service_index++;
                                    }
                                    root_description += "</serviceList>";
                                    root_description += "</device>";
                                    root_description += "</root>";
                                    request.RequestClient.Answer(root_description, "text/xml");
                                }
                                else request.RequestClient.TellNotFound();

                            }
                            else request.RequestClient.TellNotFound();
                        };
                }
            }
        }
        public void TestMediaRendererSetPlaybackUrlWithMiniWebServer()
        {
            Console.WriteLine("Test to set a playback url of a media renderer with a mini web server.");
            UPnP u = new UPnP();
            u.SetupSockets();
            MiniWebServer server = new MiniWebServer();
            server.Port = 80;
            server.SetupListeningSocket();

            bool wait = true;
            server.RequestReceived += delegate(MiniWebServer request_server, MiniWebServer.Request request)
            {
                Console.WriteLine("Request received: ");
                Console.WriteLine("URL: " + request.Url);
                Console.WriteLine("Method: " + request.Method);
                Console.WriteLine("Version: " + request.Version);
                Console.WriteLine("Headers:");
                foreach (string key in request.Headers.Keys)
                {
                    Console.WriteLine("[" + key + "]" + ":[" + request.Headers.Get(key) + "]");
                }
                if (request.Url == "/")
                {
                    string page = "";
                    //string type = "text/plain";
                    page = "<html>\n<head>\n<title>MiniWebServer Test Page</title>\n</head>\n<body bgcolor=\"#333355\">Test Page of the Miniwebserver running on port: " + server.Port + "<br><a href=\"/test.mp3\">Test Mp3</a></body>\n</html>\n";
                    string type = "text/html";
                    request.RequestClient.Answer(page, type);
                }
                else if (request.Url == "/test.mp3")
                {
                    byte[] mp3 = File.ReadAllBytes("..\\..\\..\\TestDateien\\test.mp3");
                    string type = "audio/mpeg";
                    request.RequestClient.Answer(mp3, type);
                }
            };

            u.DeviceDiscovered += delegate(Device d)
            {
                if (d.DeviceType == Device.DeviceTypes.MediaRenderer)
                {
                    MediaRenderer mr = (MediaRenderer)d;
                    mr.SettingPlaybackUrlCompleted += delegate(MediaRenderer sp, bool was_successful)
                    {
                        if (was_successful)
                            Console.WriteLine("Set a playback url.");
                        //wait = !was_successful;
                    };
                    mr.PressingButtonCompleted += delegate(MediaRenderer sp, MediaRenderer.Button pressed, bool was_successful)
                    {
                        if (was_successful)
                            Console.WriteLine("Pressed the " + Enum.GetName(typeof(MediaRenderer.Button), pressed) + " button.");
                        wait = !was_successful;
                    };

                    mr.InformationGathered += delegate(Device dimr, bool was_successful)
                    {
                        MediaRenderer mir = (MediaRenderer)dimr;
                        if (was_successful)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("-- Gathered media renderer information --");
                            Console.WriteLine("SpecVersion: " + mir.SpecVersionMajor + "." + mir.SpecVersionMinor);
                            Console.WriteLine("URLBase: " + mir.UrlBase);
                            if (mir.RootDevice != null)
                            {
                                Console.WriteLine("presentationURL: " + mir.RootDevice.PresentationUrl);
                                Console.WriteLine("friendlyName: " + mir.RootDevice.FriendlyName);
                                Console.WriteLine("manufacturer: " + mir.RootDevice.Manufacturer);
                                Console.WriteLine("manufacturerURL: " + mir.RootDevice.ManufacturerUrl);
                                Console.WriteLine("modelDescription: " + mir.RootDevice.ModelDescription);
                                Console.WriteLine("modelName: " + mir.RootDevice.ModelName);
                                Console.WriteLine("Number of Sub Devices: " + mir.RootDevice.Devices.Count);
                                Console.WriteLine("Sub UUID: " + mir.RootDevice.UniversalUniqueID);
                                //Thread.Sleep(3000);
                                mir.SetPlaybackUrl("http://" + ip + "/test.mp3");
                                Thread.Sleep(1000);
                                mir.Press(MediaRenderer.Button.Play);
                            }
                            //Console.WriteLine("Server: " + r.Server);
                            Console.WriteLine("UUID: " + mir.UniversalUniqueID);
                            Console.WriteLine("-- Gathered media renderer information --");
                            Console.WriteLine("");
                        }
                        else Console.WriteLine("failed to gather media renderer information");
                    };
                    mr.GatherInformation();//TODO this could also be done by upnp after it fired the discovered event

                    Console.WriteLine("");
                    Console.WriteLine("-- Discovered a media renderer --");
                    Console.WriteLine("Server: " + mr.Server);
                    Console.WriteLine("Host: " + mr.Host + ":" + mr.Port);
                    Console.WriteLine("UUID: " + mr.UniversalUniqueID);
                    Console.WriteLine("Location: " + mr.Location);
                    Console.WriteLine("Unique Service Name: " + mr.UniqueServiceName);
                    Console.WriteLine("-- Discovered a media renderer --");
                    Console.WriteLine("");
                    //Assert.IsTrue(!string.IsNullOrEmpty(ex_ip_completed.MyIP), "no ip address fetched");
                }
            };
            u.StartDiscovery();
            Console.WriteLine("Waiting for data");
            DateTime start = DateTime.Now;
            while (wait)
            {
                if (DateTime.Now - start > new TimeSpan(0, 0, 300))
                {
                    Console.WriteLine("");
                    Console.WriteLine("Operation took too long");
                    wait = false;
                    Assert.Fail("Operation took too long");
                }
                Console.Write(".");
                Thread.Sleep(250);
            }
            Console.WriteLine("UPnP Media Renderer Set Playback URL With Mini Web Server Test successful.");

            u.CloseSockets();
        }
        public void TestMiniWebServerRequest()
        {
            Console.WriteLine("Test to see if requesting works.");
            MiniWebServer server = new MiniWebServer();
            server.Port = 80;
            server.SetupListeningSocket();

            bool wait = true;
            server.RequestReceived += delegate(MiniWebServer request_server, MiniWebServer.Request request)
            {
                Console.WriteLine("Request received: ");
                Console.WriteLine("URL: " + request.Url);
                Console.WriteLine("Method: " + request.Method);
                Console.WriteLine("Version: " + request.Version);
                Console.WriteLine("Headers:");
                foreach (string key in request.Headers.Keys)
                {
                    Console.WriteLine("[" + key + "]" + ":[" + request.Headers.Get(key) + "]");
                }
                //request.RequestClient.TellNotFound();

                //request.RequestClient.Answer("HTTP/1.0 302 Moved Temporarily\r\nSERVER: MiniWebServer\r\nLOCATION: http://192.168.0.1:80/Public_UPNP_gatedesc.xml\r\n\r\n");
                if (request.Url == "/")
                {
                    string page = "";
                    //string type = "text/plain";
                    page = "<html>\n<head>\n<title>MiniWebServer Test Page</title>\n</head>\n<body bgcolor=\"#333355\">Test Page of the Miniwebserver running on port: " + server.Port + "<br><a href=\"/test.mp3\">Test Mp3</a></body>\n</html>\n";
                    string type = "text/html";
                    request.RequestClient.Answer(page, type);
                }
                else if (request.Url == "/test.mp3")
                {
                    byte[] mp3 = File.ReadAllBytes("..\\..\\..\\TestDateien\\test.mp3");
                    string type = "audio/mpeg";
                    request.RequestClient.Answer(mp3, type);
                }

                    //request.RequestClient.Answer("HTTP/1.1 200 OK\r\nSERVER: MiniWebServer\r\nContent-Type: text/plain\r\nContent-Length: " + page.Length + "\r\nConnection: Close\r\n\r\n" + page);

                //Thread.Sleep(300);
                //request.RequestClient.Disconnect();
                //Assert.IsTrue(!string.IsNullOrEmpty(ex_ip_completed.MyIP), "no ip address fetched");
                //wait = false;
            };
            Console.WriteLine("Waiting for data");
            DateTime start = DateTime.Now;
            while (wait)
            {
                if (DateTime.Now - start > new TimeSpan(0, 0,120))
                {
                    Console.WriteLine("");
                    Console.WriteLine("Operation took too long");
                    Assert.Fail("Operation took too long");
                    wait = false;
                }
                Console.Write(".");
                Thread.Sleep(250);
            }
            Console.WriteLine("");
            server.CloseListeningSocket();
            Console.WriteLine("Mini Web Server Request Test successful.");
        }
 public void TestMiniWebServerOpenClose()
 {
     Console.WriteLine("Test to Open/Close the Mini Web Server.");
     MiniWebServer server = new MiniWebServer();
     server.SetupListeningSocket();
     server.CloseListeningSocket();
     Console.WriteLine("Mini Web Server Open/Close Test successful.");
 }
        public void TestMiniWebServerAutoFileAnswerRequest()
        {
            Console.WriteLine("Test to see if requesting using the file answer method works.");
            MiniWebServer server = new MiniWebServer();
            server.Port = 80;
            server.SetupListeningSocket();
            long page_len = 0;
            long ret_page_len = 1; //to make sure no false positive could occur
            bool wait = true;
            server.RequestReceived += delegate(MiniWebServer request_server, MiniWebServer.Request request)
            {
                Console.WriteLine("Request received: ");
                Console.WriteLine("URL: " + request.Url);
                Console.WriteLine("Method: " + request.Method);
                Console.WriteLine("Version: " + request.Version);
                Console.WriteLine("Headers:");
                foreach (string key in request.Headers.Keys)
                {
                    Console.WriteLine("[" + key + "]" + ":[" + request.Headers.Get(key) + "]");
                }
                //request.RequestClient.TellNotFound();

                //request.RequestClient.Answer("HTTP/1.0 302 Moved Temporarily\r\nSERVER: MiniWebServer\r\nLOCATION: http://192.168.0.1:80/Public_UPNP_gatedesc.xml\r\n\r\n");
                if (request.Url == "/")
                {
                    string page = "";
                    //string type = "text/plain";
                    page = "<html>\n<head>\n<title>MiniWebServer Test Page</title>\n</head>\n<body bgcolor=\"#333355\">Test Page of the Miniwebserver running on port: " + server.Port + "<br><a href=\"/test.mp3\">Test Mp3</a></body>\n</html>\n";
                    string type = "text/html";
                    page_len = page.Length;
                    request.RequestClient.Answer(page, type);
                }
                else if (request.Url == "/test.mp3")
                {
                    FileInfo fi = new FileInfo("..\\..\\..\\TestDateien\\test.mp3");
                    page_len = fi.Length;
                    request.RequestClient.FileAnswer("..\\..\\..\\TestDateien\\test.mp3");
                }

                //request.RequestClient.Answer("HTTP/1.1 200 OK\r\nSERVER: MiniWebServer\r\nContent-Type: text/plain\r\nContent-Length: " + page.Length + "\r\nConnection: Close\r\n\r\n" + page);

                //Thread.Sleep(300);
                //request.RequestClient.Disconnect();
                //Assert.IsTrue(!string.IsNullOrEmpty(ex_ip_completed.MyIP), "no ip address fetched");
                //wait = false;
            };

            WebClient wc = new WebClient();
            wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e)
            {
                if (!e.Cancelled && e.Result != null)
                {
                    for (int i = 0; i < wc.ResponseHeaders.Count; i++)
                    {
                        Console.WriteLine("Header[" + i + "]: " + wc.ResponseHeaders.GetKey(i)+" : "+wc.ResponseHeaders[i]);
                    }
                    //Console.WriteLine("Content-Type: " + wc.Headers.Get("Content-Type"));
                    ret_page_len = e.Result.Length;
                    wait = false;
                }
            };
            wc.DownloadDataAsync(new Uri("http://127.0.0.1/test.mp3"));

            Console.WriteLine("Waiting for data");
            DateTime start = DateTime.Now;
            while (wait)
            {
                if (DateTime.Now - start > new TimeSpan(0, 0, 120))
                {
                    Console.WriteLine("");
                    Console.WriteLine("Operation took too long");
                    Assert.Fail("Operation took too long");
                    wait = false;
                }
                Console.Write(".");
                Thread.Sleep(250);
            }
            Assert.IsTrue(page_len == ret_page_len, "Test failed: received an incomplete page");
            Console.WriteLine("");
            server.CloseListeningSocket();
            wc.Dispose();
            Console.WriteLine("Mini Web Server Request using File Answer Method Test successful.");
        }