/// <summary>
        /// Initializes a new instance
        /// </summary>
        /// <param name="version">Version Number</param>
        /// <param name="Service_ID">USN, if blank a new GUID will be created for you</param>
        /// <param name="Service_Type">The Type</param>
        /// <param name="IsStandard">True if standard, false if domain specific</param>
        public ServiceDescription(double version, String Service_ID, String Service_Type, bool IsStandard)
        {
            IsStandardService = IsStandard;
            if (Service_ID == "") {
                ServiceID = Guid.NewGuid ().ToString ();
            } else {
                ServiceID = Service_ID;
            }
            ServiceType = Service_Type;

            SCPDURL = "{" + Service_ID + "}scpd.xml";
            ControlURL = "{" + Service_ID + "}control";
            EventURL = "{" + Service_ID + "}event";

            if (version == 0) {
                Major = 1;
                Minor = 0;
            } else {
                DText TempNum = new DText ();
                Major = int.Parse (TempNum.FIELD (version.ToString (), ".", 1));
                if (TempNum.DCOUNT (version.ToString (), ".") == 2) {
                    Minor = int.Parse (TempNum.FIELD (version.ToString (), ".", 2));
                } else {
                    Minor = 0;
                }
            }
        }
示例#2
0
        public static string GetURNPrefix(string urn)
        {
            int   len;
            DText p = new DText();

            p.ATTRMARK = ":";
            p[0]       = urn;
            len        = p[p.DCOUNT()].Length;
            return(urn.Substring(0, urn.Length - len));
        }
示例#3
0
        /// <summary>
        /// Method executes when a contentdirectory events a change in a container.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="NewValue"></param>
        private void Sink_OnContainerUpdateIDsChanged(CpContentDirectory sender, System.String NewValue)
        {
            string    csv_containers = NewValue;
            Hashtable cache          = new Hashtable();
            DText     parser         = new DText();
            DText     parser2        = new DText();

            parser.ATTRMARK  = ",";
            parser2.ATTRMARK = ",";

            if (csv_containers != "")
            {
                parser[0] = csv_containers;
                int dcnt = parser.DCOUNT();

                for (int i = 1; i <= dcnt; i++)
                {
                    string id, update;
                    if (Accumulator_ContainerUpdateIDs.Delimitor == ",")
                    {
                        id     = parser[i++];
                        update = parser[i];
                    }
                    else
                    {
                        string pair = parser[i];
                        parser2[0] = pair;
                        id         = parser2[1];
                        update     = parser2[2];
                    }

                    CpMediaContainer cpc = (CpMediaContainer)this.GetDescendent(id, cache);

                    if (cpc != null)
                    {
                        try
                        {
                            UInt32 updateId = UInt32.Parse(update);
                            if (updateId != cpc.UpdateID)
                            {
                                cpc.ForceUpdate(false);
                            }
                        }
                        catch
                        {
                            cpc.ForceUpdate(false);
                        }
                    }
                }
            }

            cache.Clear();
        }
        public static MediaItem PopulateMetaData(MediaResource R, FileInfo F)
        {
            MediaItem RetVal;

            MediaBuilder.item Item   = null;
            DText             parser = new DText();

            parser.ATTRMARK = "-";
            parser.MULTMARK = ".";

            switch (F.Extension.ToUpper())
            {
            case ".MP3":
                Item = ParseMP3_V1(F);
                if (Item == null)
                {
                    parser[0] = F.Name;
                    if (parser.DCOUNT() == 2)
                    {
                        Item         = new MediaBuilder.musicTrack(parser[2, 1].Trim());
                        Item.creator = parser[1].Trim();
                        ((MediaBuilder.musicTrack)Item).artist = new PersonWithRole[1] {
                            new PersonWithRole()
                        };
                        ((MediaBuilder.musicTrack)Item).artist[0].Name = Item.creator;
                        ((MediaBuilder.musicTrack)Item).artist[0].Role = null;
                    }
                }
                break;
            }

            if (Item != null)
            {
                RetVal = MediaBuilder.CreateItem(Item);
                RetVal.AddResource(R);
                return(RetVal);
            }
            else
            {
                // Create a Generic Item
                string fname    = F.Name;
                int    fnameidx = fname.IndexOf(".");
                if (fnameidx != -1)
                {
                    fname = fname.Substring(0, fnameidx);
                }
                MediaBuilder.item genericItem = new MediaBuilder.item(fname);
                RetVal = MediaBuilder.CreateItem(genericItem);
                RetVal.AddResource(R);
                return(RetVal);
            }
        }
        /// <summary>
        /// <para>
        /// Instantiates a sorter based on the sortCriteria string. The basic algorithm for
        /// sorting is to supply a comma-separated-value (CSV) listing of property names
        /// (easily retrieved from using <see cref="Tags"/>'s indexer with the
        /// <see cref="CommonPropertyNames"/>,
        /// <see cref="_DC"/>,
        /// <see cref="_UPNP"/>, or
        /// <see cref="_ATTRIB"/>
        /// enumerators.)
        /// with each property name having a + or - sign to indicate ascending or descending
        /// order of the sorting for that property name. Assuming "T" is an instance of a
        /// <see cref="Tags"/> object.
        /// Example below.
        /// </para>
        ///
        /// <para>
        /// <list type="table">
        /// <item>
        /// <term>"+" +T[CommonPropertyNames.title]+ ",-" +T[CommonPropertyNames.creator]</term>
        /// <description>Sorts with ascending titles first, then descending creators</description>
        /// </item>
        /// </list>
        /// </para>
        ///
        /// </summary>
        /// <param name="forceDistinction">if true, then any comparison that evaluates to equal will force an arbitrary ordering of the two objects in question</param>
        /// <param name="sortCriteria">a string with the property names in a CSV list, where
        /// each property name has a + or - sign to indicate ascending or descending order</param>
        public MediaSorter(bool forceDistinction, string sortCriteria)
        {
            this.forceDistinction = forceDistinction;

            if (sortCriteria != null)
            {
                if (sortCriteria != "")
                {
                    DText parser = new DText();
                    parser.ATTRMARK = ",";
                    parser[0]       = sortCriteria;

                    int size = parser.DCOUNT();
                    this.sortKeys = new ArrayList(size);

                    // iterate through properties for sorting
                    //
                    for (int i = 1; i <= size; i++)
                    {
                        string prop    = parser[i].Trim();
                        char   asc_dsc = prop[0];

                        string property = prop.Substring(1);

                        bool ascending = true;
                        if (asc_dsc == '-')
                        {
                            ascending = false;
                        }
                        else if (asc_dsc == '+')
                        {
                            ascending = true;
                        }
                        else
                        {
                            throw new UPnPCustomException(709, "Invalid sort flag.");
                        }

                        MetadataValueComparer mvc = new MetadataValueComparer(property, ascending);

                        this.sortKeys.Add(mvc);
                    }
                }
            }

            if (this.sortKeys == null)
            {
                this.sortKeys = new ArrayList(0);
            }
        }
        /// <summary>
        /// This method is called whenever we need to inspect a list of ConnectionIDs
        /// to see if any of them are new
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="IDString"></param>
        /// <param name="e"></param>
        /// <param name="Handle"></param>
        protected void IDSink(CpConnectionManager sender, string IDString, UPnPInvokeException e, object Handle)
        {
            if ((e != null) || (IDString == ""))
            {
                return;
            }

            // This is a temp parser that will parse the CSV list of IDs
            DText p = new DText();

            p.ATTRMARK = ",";
            p[0]       = IDString;
            int len = p.DCOUNT();

            for (int i = 1; i <= len; ++i)
            {
//				bool FOUND = false;
                int cid = int.Parse(p[i].Trim());

//				lock(InstanceList)
//				{
//					foreach(AVConnection _AVC in InstanceList)
//					{
//						if(_AVC.ConnectionID == cid)
//						{
//							FOUND = true;
//							break;
//						}
//					}
//				}

                lock (this.CreateConnectionLock)
                {
                    if (this.PendingCreateConnection == 0)
                    {
                        ConnectionManager.GetCurrentConnectionInfo(cid, null, new CpConnectionManager.Delegate_OnResult_GetCurrentConnectionInfo(ConnectionInfoSink));
                    }
                    else
                    {
                        // We possible need to wait a maximum of 30 seconds, just in case events arrive
                        // that involve this connection ID. When/if that happens, we will remove this
                        // object from the monitor, and continue directly.
                        this.ConnectionMonitor.Add(cid, 30);
                    }
                }
            }
        }
        /// <summary>
        /// This method is triggered whenever a ConnectionManagerEvent arrives, which tells us
        /// all of the current ConnectionIDs
        /// </summary>
        /// <param name="sender">The CpConnectionManager class that sent the event</param>
        /// <param name="CurrentIDs">A CSV list of ConnectionIDs</param>
        protected void ConnectionIDEventSink(CpConnectionManager sender, string CurrentIDs)
        {
            // We need to return immediately if this flag is set.
            // This flag is only set if PrepareForConnection in not implemented on this
            // renderer, in which case, there will be a default ConnectionID of 0, which
            // must never disappear.
            if (DontEverDelete == true)
            {
                return;
            }

            // This is a temp collection used to create an index of the ConnectionIDs that
            // were recieved in this event
            Hashtable h = new Hashtable();
            // This is a temp parser used to parse the CSV list of IDs
            DText p = new DText();

            p.ATTRMARK = ",";

            if (CurrentIDs != "")
            {
                p[0] = CurrentIDs;
                int len = p.DCOUNT();
                for (int i = 1; i <= len; ++i)
                {
                    // Adding a ConnectionID into the temp collection
                    h[Int32.Parse(p[i])] = "";
                }
            }

            // Lets find ones that were removed first
            foreach (AVConnection a in Connections)
            {
                if (h.ContainsKey(a.ConnectionID) == false)
                {
                    // This ID was removed
                    InstanceList.Remove(a);
                    a.Dispose();
                    OnRemovedConnectionEvent.Fire(this, a, Guid.NewGuid().GetHashCode());
                }
            }

            // Now lets look for new ones... This is easy
            IDSink(sender, CurrentIDs, null, Guid.NewGuid().GetHashCode());
        }
        /// <summary>
        /// This method is called when an AsyncCall to GetProtocolInfo completes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="Source"></param>
        /// <param name="Sink"></param>
        /// <param name="e"></param>
        /// <param name="Handle"></param>
        protected void GetProtocolInfoSink(CpConnectionManager sender, System.String Source, System.String Sink, UPnPInvokeException e, object Handle)
        {
            if (e != null)
            {
                return;
            }
            if (Sink == "")
            {
                return;
            }

            // This is a temp parser to parse the supported ProtocolInfo values
            DText p = new DText();

            p.ATTRMARK = ",";
            p[0]       = Sink;
            int len = p.DCOUNT();
            ProtocolInfoString istring;

            for (int i = 1; i <= len; ++i)
            {
                istring = new ProtocolInfoString(p[i]);
                // Add each individual entry
                ProtocolInfoList.Add(istring);
            }
            if (!this.__Init)
            {
                this.__Init = true;
                // Upon discovery of a renderer, we can't return the renderer to the user
                // until we at least parsed the supported ProtocolInfo values, otherwise
                // the user will experience incorrect behavior. Since we have just parsed
                // these values, we can fire this event.
                if (this.OnInitialized != null)
                {
                    OnInitialized(this);
                }
            }
        }
        /// <summary>
        /// This method gets called when a new Request is received
        /// </summary>
        /// <param name="request"></param>
        /// <param name="WebSession"></param>
        protected void ReceiveSink(HTTPMessage request, HTTPSession WebSession)
        {
            HTTPMessage  rsp = new HTTPMessage();
            UTF8Encoding U   = new UTF8Encoding();

            if ((request.Directive == "HEAD") ||
                (request.Directive == "GET"))
            {
                if (request.DirectiveObj == "/item.m3u")
                {/*
                  *                     rsp.StatusCode = 200;
                  *                     rsp.StatusData = "OK";
                  *                     rsp.ContentType = "audio/mpegurl";
                  *                     rsp.StringBuffer = M3UString;
                  */
                    string r = request.GetTag("Range");
                    if (r == "")
                    {
                        rsp.StatusCode   = 200;
                        rsp.StatusData   = "OK";
                        rsp.ContentType  = "audio/mpegurl";
                        rsp.StringBuffer = M3UString;
                    }
                    else
                    {
                        rsp.StatusCode  = 206;
                        rsp.StatusData  = "Partial Content";
                        rsp.ContentType = "audio/mpegurl";

                        DText rp0 = new DText();
                        rp0.ATTRMARK = "=";
                        rp0[0]       = r;
                        DText rp = new DText();
                        rp.ATTRMARK = "-";
                        rp[0]       = rp0[2].Trim();
                        if (rp[1] == "")
                        {
                            // LastBytes
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length)
                                {
                                    rsp.AddTag("Content-Range", "bytes 0-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString;
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + (M3UString.Length - int.Parse(rp[2])).ToString() + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(M3UString.Length - int.Parse(rp[2]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else if (rp[2] == "")
                        {
                            // Offset till end
                            try
                            {
                                rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else
                        {
                            // Range
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length + 1)
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + (M3UString.Length - 1).ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + rp[2] + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]), 1 + int.Parse(rp[2]) - int.Parse(rp[1]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp            = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        int    i        = request.DirectiveObj.LastIndexOf("/");
                        string tmp      = request.DirectiveObj.Substring(1, i - 1);
                        bool   hasRange = true;
                        if (tmp.IndexOf("/") != -1)
                        {
                            tmp = tmp.Substring(0, tmp.IndexOf("/"));
                        }

                        if (FileInfoTable.ContainsKey(tmp))
                        {
                            FileInfo f;
                            if (FileInfoTable[tmp].GetType() == typeof(string))
                            {
                                f = new FileInfo((string)FileInfoTable[tmp]);
                                FileInfoTable[tmp] = f;
                            }
                            else
                            {
                                f = (FileInfo)FileInfoTable[tmp];
                            }
                            ProtocolInfoString pis = ProtocolInfoString.CreateHttpGetProtocolInfoString(f);
                            rsp.StatusCode  = 200;
                            rsp.StatusData  = "OK";
                            rsp.ContentType = pis.MimeType;
                            if (request.Directive == "HEAD")
                            {
                                rsp.AddTag("Content-Length", f.Length.ToString());
                                rsp.OverrideContentLength = true;
                            }
                            else
                            {
                                HTTPSession.Range[] RNG = null;
                                if (request.GetTag("Range") != "")
                                {
                                    long      x, y;
                                    ArrayList RList = new ArrayList();
                                    DText     rp    = new DText();
                                    rp.ATTRMARK = "=";
                                    rp.MULTMARK = ",";
                                    rp.SUBVMARK = "-";
                                    rp[0]       = request.GetTag("Range");

                                    for (int I = 1; I <= rp.DCOUNT(2); ++I)
                                    {
                                        if (rp[2, I, 1] == "")
                                        {
                                            // Final Bytes
                                            y = long.Parse(rp[2, I, 2].Trim());
                                            x = f.Length - y;
                                            y = x + y;
                                        }
                                        else if (rp[2, I, 2] == "")
                                        {
                                            // Offset till end
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = f.Length - x;
                                        }
                                        else
                                        {
                                            // Full Range
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = long.Parse(rp[2, I, 2].Trim());
                                        }
                                        RList.Add(new HTTPSession.Range(x, 1 + y - x));
                                    }
                                    RNG = (HTTPSession.Range[])RList.ToArray(typeof(HTTPSession.Range));
                                }
                                else
                                {
                                    hasRange = false;
                                }

                                if (request.Version == "1.0")
                                {
                                    WebSession.OnStreamDone += new HTTPSession.StreamDoneHandler(DoneSink);
                                }
                                //								((HTTPMessage)(new UPnPDebugObject(WebSession)).GetField("Headers")).Version = "1.0";
                                if (hasRange)
                                {
                                    WebSession.SendStreamObject(f.OpenRead(), RNG, pis.MimeType);
                                }
                                else
                                {
                                    FileStream fs     = f.OpenRead();
                                    long       length = fs.Length;
                                    WebSession.SendStreamObject(fs, length, pis.MimeType);
                                }
                                return;
                            }
                        }
                        else
                        {
                            rsp.StatusCode = 404;
                            rsp.StatusData = "Not Found";
                        }
                    }
                    catch (Exception)
                    {
                        rsp.StatusCode = 404;
                        rsp.StatusData = "Not Found";
                    }
                }
                WebSession.Send(rsp);
                return;
            }

            rsp.StatusCode = 500;
            rsp.StatusData = "Not implemented";
            WebSession.Send(rsp);
        }
        public override void Start(UPnPDevice device)
        {
            UPnPTestStates Master = UPnPTestStates.Pass;

            TestDevice = device;
            UPnPDevice d = device;

            UPnPService[] services = d.GetServices(CpConnectionManager.SERVICE_NAME);

            if (services == null || services.Length == 0)
            {
                enabled = false;
                return;
            }

            CM = new CpConnectionManager(services[0]);

            string SOURCE = "";
            string SINK   = "";
            DText  parser = new DText();

            StartCountDown(0, 90);
            try
            {
                CM.Sync_GetProtocolInfo(out SOURCE, out SINK);
            }
            catch (UPnPInvokeException)
            {
                Results.Add("Connection Handler Test was aborted because GetProtocolInfo FAILED");
                SetState("Connection Handling", UPnPTestStates.Failed);
                Master = UPnPTestStates.Failed;
            }
            AbortCountDown();

            parser.ATTRMARK = ",";
            parser.MULTMARK = ":";

            bool OK = true;

            if (ConnectionManagerEventsTest() == false)
            {
                Results.Add("Connection Handler Test was aborted because of invalid/missing events");
                SetState("Connection Handling", UPnPTestStates.Failed);
                Master = UPnPTestStates.Failed;
            }

            if (SINK != "")
            {
                parser[0]   = SINK;
                TotalTime   = parser.DCOUNT() * 120;
                CurrentTime = 0;
                for (int i = 1; i <= parser.DCOUNT(); ++i)
                {
                    if (parser.DCOUNT(i) != 4)
                    {
                        // Invalid Format
                        OK = false;
                        AddEvent(LogImportance.Critical, "Connection Handling", "   Protocol Info String [" + parser[i] + "] is not in a valid format");
                    }
                }
                if (OK)
                {
                    AddEvent(LogImportance.Remark, "Connection Handling", "   Protocol Info Strings are in the correct format");
                }
                else
                {
                    Results.Add("Connection Handler Test was aborted because of invalid Protocol Info Strings");
                    SetState("Connection Handling", UPnPTestStates.Failed);
                    Master = UPnPTestStates.Failed;
                }

                if (CM.HasAction_PrepareForConnection)
                {
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (PrepareForConnectionTest_SINK(parser[i]) == false)
                        {
                            OK = false;
                        }
                    }
                }
            }

            if (OK)
            {
                Results.Add("Connection Handler Test PASSED");
                SetState("Connection Handling", UPnPTestStates.Pass);
            }
            else
            {
                Results.Add("Connection Handler Test FAILED");
                SetState("Connection Handling", UPnPTestStates.Failed);
                Master = UPnPTestStates.Failed;
            }

            OK = true;
            UPnPService[] _AVT = d.GetServices(CpAVTransport.SERVICE_NAME);
            if (_AVT.Length != 0)
            {
                // AVT Tests
                AVT = new CpAVTransport(_AVT[0]);
                if (!Test_AVTransport_LastChange())
                {
                    OK = false;
                }
            }
            if (OK)
            {
                Results.Add("Event Formatting PASSED");
                SetState("Event Formatting", UPnPTestStates.Pass);
            }
            else
            {
                Results.Add("Event Formatting FAILED");
                SetState("Event Formatting", UPnPTestStates.Failed);
                Master = UPnPTestStates.Failed;
            }

            OK   = true;
            _AVT = d.GetServices(CpAVTransport.SERVICE_NAME);
            if (_AVT.Length != 0)
            {
                // AVT Tests
                AVT = new CpAVTransport(_AVT[0]);
                if (!Test_AVTransport_StateVariables())
                {
                    OK = false;
                }
            }
            if (OK)
            {
                Results.Add("StateVariable Values NOT TESTED (Not implemented)");
                SetState("StateVariable Values", UPnPTestStates.Pass);
            }
            else
            {
                Results.Add("StateVariable Values FAILED");
                SetState("StateVariable Values", UPnPTestStates.Failed);
                Master = UPnPTestStates.Failed;
            }

//			this.HTTP_ScenarioTest();

            state = Master;
        }
        private void startMenuItem_Click(object sender, System.EventArgs e)
        {
            startMenuItem.Enabled = false;
            foreach (MenuItem i in pfcMenuItem.MenuItems)
            {
                i.Enabled = false;
            }
            foreach (MenuItem i in menuItem3.MenuItems)
            {
                i.Enabled = false;
            }
            InfoStringBox.Enabled = false;

            device = UPnPDevice.CreateRootDevice(900, 1, "");
            device.UniqueDeviceName   = Guid.NewGuid().ToString();
            device.StandardDeviceType = "MediaRenderer";
            device.FriendlyName       = "Media Renderer (" + System.Net.Dns.GetHostName() + ")";
            device.HasPresentation    = false;

            device.Manufacturer     = "OpenSource";
            device.ManufacturerURL  = "http://opentools.homeip.net/";
            device.PresentationURL  = "/";
            device.HasPresentation  = true;
            device.ModelName        = "AV Renderer";
            device.ModelDescription = "Media Renderer Device";
            device.ModelURL         = new Uri("http://opentools.homeip.net/");

            UPnPService ts = new UPnPService(1, "EmptyService", "EmptyService", true, this);

            ts.AddMethod("NullMethod");
            //device.AddService(ts);


            DText p = new DText();

            p.ATTRMARK = "\r\n";
            p[0]       = this.InfoStringBox.Text;
            int len = p.DCOUNT();

            ProtocolInfoString[] istring = new ProtocolInfoString[len];
            for (int i = 1; i <= len; ++i)
            {
                istring[i - 1] = new ProtocolInfoString(p[i]);
            }
            r = new AVRenderer(MaxConnections, istring, new AVRenderer.ConnectionHandler(NewConnectionSink));

            r.OnClosedConnection += new AVRenderer.ConnectionHandler(ClosedConnectionSink);

            if (supportRecordMenuItem.Checked == false)
            {
                r.AVT.RemoveAction_Record();
            }

            if (supportRecordQualityMenuItem.Checked == false)
            {
                r.AVT.RemoveAction_SetRecordQualityMode();
            }

            if (supportNextContentUriMenuItem.Checked == false)
            {
                r.AVT.RemoveAction_SetNextAVTransportURI();
            }

            if (MaxConnections == 0)
            {
                r.Manager.RemoveAction_PrepareForConnection();
                r.Manager.RemoveAction_ConnectionComplete();
            }

            r.AVT.GetUPnPService().GetStateVariableObject("CurrentPlayMode").AllowedStringValues = new String[3] {
                "NORMAL", "REPEAT_ALL", "INTRO"
            };

            r.Control.GetUPnPService().GetStateVariableObject("A_ARG_TYPE_Channel").AllowedStringValues = new String[3] {
                "Master", "LF", "RF"
            };
            r.Control.GetUPnPService().GetStateVariableObject("RedVideoBlackLevel").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("GreenVideoBlackLevel").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("BlueVideoBlackLevel").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("RedVideoGain").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("GreenVideoGain").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("BlueVideoGain").SetRange((ushort)0, (ushort)100, (ushort)1);

            r.Control.GetUPnPService().GetStateVariableObject("Brightness").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("Contrast").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("Sharpness").SetRange((ushort)0, (ushort)100, (ushort)1);
            r.Control.GetUPnPService().GetStateVariableObject("Volume").SetRange((UInt16)0, (UInt16)100, (ushort)1);

            device.AddService(r.Control);
            device.AddService(r.AVT);
            device.AddService(r.Manager);

            //device.AddDevice(r);

            device.StartDevice();

            //r.Start();
        }
示例#12
0
        /// <summary>
        /// Parses 'rangeStr' for HTTP range sets, and adds the sets into
        /// 'rangeSets'... should an overlapping range set be provided
        /// or if an otherwise invalid range is requested, then we clear
        /// the 'rangeSets'... behavior is taken from http://www.freesoft.org/CIE/RFC/2068/178.htm.
        ///
        /// <para>
        /// If the server ignores a byte-range-spec because it is invalid,
        /// the server should treat the request as if the invalid Range header
        /// field did not exist.
        /// (Normally, this means return a 200 response containing the full entity).
        /// The reason is that the only time a client will make such an invalid
        /// request is when the entity is smaller than the entity retrieved by a prior request.
        /// [source: http://www.freesoft.org/CIE/RFC/2068/178.htm]
        /// </para>
        /// </summary>
        /// <param name="rangeSets">this ArrayList has range sets added to it</param>
        /// <param name="rangeStr">
        /// This is the HTTP header with the desired ranges.
        /// Text is assumed to be all lower case and trimmed.
        /// </param>
        /// <param name="contentLength">
        /// The entire length of the content, from byte 0.
        /// </param>
        public static void AddRange(this List <HTTPSession.Range> rangeSets, string rangeStr, long contentLength)
        {
            if (String.IsNullOrEmpty(rangeStr))
            {
                return;
            }

            bool errorEncountered = true;

            errorEncountered = false;
            DText dt = new DText();

            dt.ATTRMARK = "=";
            dt.MULTMARK = ",";
            dt.SUBVMARK = "-";
            dt[0]       = rangeStr;

            int numSets = dt.DCOUNT(2);

            for (int i = 1; i <= numSets; i++)
            {
                string sOffset = dt[2, i, 1].Trim();
                string sEnd = dt[2, i, 2].Trim();
                long   offset = -1, length = -1, end = -1;

                if ((sOffset == "") && (sEnd == ""))
                {
                    // royally screwed up request
                    errorEncountered = true;
                    break;
                }
                else if ((sOffset == "") && (sEnd != ""))
                {
                    // retrieve the last set of bytes identified by sEnd
                    try
                    {
                        offset = 0;
                        end    = long.Parse(sEnd);
                        length = end + 1;
                    }
                    catch
                    {
                        errorEncountered = true;
                        break;
                    }
                }
                else if ((sOffset != "") && (sEnd == ""))
                {
                    // retrieve all bytes starting from sOffset
                    try
                    {
                        offset = long.Parse(sOffset);
                        end    = contentLength - 1;
                        length = contentLength - offset;
                    }
                    catch
                    {
                        errorEncountered = true;
                        break;
                    }
                }
                else
                {
                    // retrieve bytes from sOffset through sEnd,
                    // inclusive so be sure to add 1 to difference
                    try
                    {
                        offset = long.Parse(sOffset);
                        end    = long.Parse(sEnd);

                        if (offset <= end)
                        {
                            length = end - offset + 1;
                        }
                        else
                        {
                            errorEncountered = true;
                        }
                    }
                    catch
                    {
                        errorEncountered = true;
                        break;
                    }
                }

                if (errorEncountered == false)
                {
                    Debug.Assert(offset >= 0);
                    Debug.Assert(length >= 0);
                    Debug.Assert(end >= 0);

                    HTTPSession.Range newRange = new HTTPSession.Range(offset, length);
                    rangeSets.Add(newRange);
                }
            }

            if (errorEncountered)
            {
                // error parsing value, this is invalid so clear and return
                rangeSets.Clear();
            }
        }
示例#13
0
        /// <summary>
        /// This method gets called when a new Request is received
        /// </summary>
        /// <param name="request"></param>
        /// <param name="WebSession"></param>
        protected void ReceiveSink(HTTPMessage request, HTTPSession WebSession)
        {
            HTTPMessage rsp = new HTTPMessage();
            UTF8Encoding U = new UTF8Encoding();

            if ((request.Directive == "HEAD") ||
                (request.Directive == "GET"))
            {
                if (request.DirectiveObj == "/item.m3u")
                {/*
					rsp.StatusCode = 200;
					rsp.StatusData = "OK";
					rsp.ContentType = "audio/mpegurl";
					rsp.StringBuffer = M3UString;
					*/

                    string r = request.GetTag("Range");
                    if (r == "")
                    {
                        rsp.StatusCode = 200;
                        rsp.StatusData = "OK";
                        rsp.ContentType = "audio/mpegurl";
                        rsp.StringBuffer = M3UString;
                    }
                    else
                    {
                        rsp.StatusCode = 206;
                        rsp.StatusData = "Partial Content";
                        rsp.ContentType = "audio/mpegurl";

                        DText rp0 = new DText();
                        rp0.ATTRMARK = "=";
                        rp0[0] = r;
                        DText rp = new DText();
                        rp.ATTRMARK = "-";
                        rp[0] = rp0[2].Trim();
                        if (rp[1] == "")
                        {
                            // LastBytes
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length)
                                {
                                    rsp.AddTag("Content-Range", "bytes 0-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString;
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + (M3UString.Length - int.Parse(rp[2])).ToString() + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(M3UString.Length - int.Parse(rp[2]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                        else if (rp[2] == "")
                        {
                            // Offset till end
                            try
                            {
                                rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + M3UString.Length.ToString() + "/" + M3UString.Length.ToString());
                                rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }

                        }
                        else
                        {
                            // Range
                            try
                            {
                                if (int.Parse(rp[2]) > M3UString.Length + 1)
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + (M3UString.Length - 1).ToString() + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]));
                                }
                                else
                                {
                                    rsp.AddTag("Content-Range", "bytes " + rp[1] + "-" + rp[2] + "/" + M3UString.Length.ToString());
                                    rsp.StringBuffer = M3UString.Substring(int.Parse(rp[1]), 1 + int.Parse(rp[2]) - int.Parse(rp[1]));
                                }
                            }
                            catch (Exception)
                            {
                                rsp = new HTTPMessage();
                                rsp.StatusCode = 400;
                                rsp.StatusData = "Bad Request";
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        int i = request.DirectiveObj.LastIndexOf("/");
                        string tmp = request.DirectiveObj.Substring(1, i - 1);
                        bool hasRange = true;
                        if (tmp.IndexOf("/") != -1)
                        {
                            tmp = tmp.Substring(0, tmp.IndexOf("/"));
                        }

                        if (FileInfoTable.ContainsKey(tmp))
                        {
                            FileInfo f;
                            if (FileInfoTable[tmp].GetType() == typeof(string))
                            {
                                f = new FileInfo((string)FileInfoTable[tmp]);
                                FileInfoTable[tmp] = f;
                            }
                            else
                            {
                                f = (FileInfo)FileInfoTable[tmp];
                            }
                            ProtocolInfoString pis = ProtocolInfoString.CreateHttpGetProtocolInfoString(f);
                            rsp.StatusCode = 200;
                            rsp.StatusData = "OK";
                            rsp.ContentType = pis.MimeType;
                            if (request.Directive == "HEAD")
                            {
                                rsp.AddTag("Content-Length", f.Length.ToString());
                                rsp.OverrideContentLength = true;
                            }
                            else
                            {
                                HTTPSession.Range[] RNG = null;
                                if (request.GetTag("Range") != "")
                                {
                                    long x, y;
                                    ArrayList RList = new ArrayList();
                                    DText rp = new DText();
                                    rp.ATTRMARK = "=";
                                    rp.MULTMARK = ",";
                                    rp.SUBVMARK = "-";
                                    rp[0] = request.GetTag("Range");

                                    for (int I = 1; I <= rp.DCOUNT(2); ++I)
                                    {
                                        if (rp[2, I, 1] == "")
                                        {
                                            // Final Bytes
                                            y = long.Parse(rp[2, I, 2].Trim());
                                            x = f.Length - y;
                                            y = x + y;
                                        }
                                        else if (rp[2, I, 2] == "")
                                        {
                                            // Offset till end
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = f.Length - x;
                                        }
                                        else
                                        {
                                            // Full Range
                                            x = long.Parse(rp[2, I, 1].Trim());
                                            y = long.Parse(rp[2, I, 2].Trim());
                                        }
                                        RList.Add(new HTTPSession.Range(x, 1 + y - x));
                                    }
                                    RNG = (HTTPSession.Range[])RList.ToArray(typeof(HTTPSession.Range));
                                }
                                else
                                {
                                    hasRange = false;
                                }

                                if (request.Version == "1.0")
                                {
                                    WebSession.OnStreamDone += new HTTPSession.StreamDoneHandler(DoneSink);
                                }
                                //								((HTTPMessage)(new UPnPDebugObject(WebSession)).GetField("Headers")).Version = "1.0";
                                if (hasRange)
                                {
                                    WebSession.SendStreamObject(f.OpenRead(), RNG, pis.MimeType);
                                }
                                else
                                {
                                    FileStream fs = f.OpenRead();
                                    long length = fs.Length;
                                    WebSession.SendStreamObject(fs, length, pis.MimeType);
                                }
                                return;
                            }
                        }
                        else
                        {
                            rsp.StatusCode = 404;
                            rsp.StatusData = "Not Found";
                        }
                    }
                    catch (Exception)
                    {
                        rsp.StatusCode = 404;
                        rsp.StatusData = "Not Found";
                    }
                }
                WebSession.Send(rsp);
                return;
            }

            rsp.StatusCode = 500;
            rsp.StatusData = "Not implemented";
            WebSession.Send(rsp);
        }
        /// <summary>
        /// Method executes when a contentdirectory events a change in a container.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="NewValue"></param>
        private void Sink_OnContainerUpdateIDsChanged(CpContentDirectory sender, System.String NewValue)
        {
            string csv_containers = NewValue;
            Hashtable cache = new Hashtable();
            DText parser = new DText();
            DText parser2 = new DText();
            parser.ATTRMARK = ",";
            parser2.ATTRMARK = ",";

            if (csv_containers != "")
            {
                parser[0] = csv_containers;
                int dcnt = parser.DCOUNT();

                for (int i=1; i <= dcnt; i++)
                {
                    string id, update;
                    if (Accumulator_ContainerUpdateIDs.Delimitor == ",")
                    {
                        id = parser[i++];
                        update = parser[i];
                    }
                    else
                    {
                        string pair = parser[i];
                        parser2[0] = pair;
                        id = parser2[1];
                        update = parser2[2];
                    }

                    CpMediaContainer cpc = (CpMediaContainer) this.GetDescendent(id, cache);

                    if (cpc !=null)
                    {
                        try
                        {
                            UInt32 updateId = UInt32.Parse(update);
                            if (updateId != cpc.UpdateID)
                            {
                                cpc.ForceUpdate(false);
                            }
                        }
                        catch
                        {
                            cpc.ForceUpdate(false);
                        }
                    }
                }
            }

            cache.Clear();
        }
        /// <summary>
        /// This method is called automatically by the UPNP stack when eventing the
        /// ContainerUpdateIDs. Programmers need only set the value of the ContainerUpdateIDs
        /// state variable with a single elem
        /// </summary>
        /// <param name="current">Comma-separated-value list in the string form of "[containerID] UpdateID= [container.UpdateID], [containerIDn] UpdateID= [container.UpdatedID]"</param>
        /// <param name="newObject">String that should overwrite an existing comma-separated-value item or append to the existing list, in form "[containerID] UpdateID= [container.UpdateID]"</param>
        /// <returns></returns>
        public object Merge(object current, object newObject)
        {
            DText Parser = new DText();

            Parser.ATTRMARK = Accumulator_ContainerUpdateIDs.CSV_Delimitor;

            DText Parser2 = new DText();

            Parser2.ATTRMARK = Accumulator_ContainerUpdateIDs.Delimitor;

            if (current == null)
            {
                current = "";
            }
            if (newObject == null)
            {
                newObject = "";
            }

            string curStr = current.ToString();
            string newStr = newObject.ToString();

            if (newStr == "")
            {
                return("");
            }

            int       i;
            Hashtable hash = new Hashtable();

            if (curStr != "")
            {
                Parser[0] = curStr;
                int cnt = Parser.DCOUNT();
                for (i = 1; i <= cnt; i++)
                {
                    string id, update;
                    if (Accumulator_ContainerUpdateIDs.Delimitor == Accumulator_ContainerUpdateIDs.CSV_Delimitor)
                    {
                        id = Parser[i];
                        i++;
                        update   = Parser[i];
                        hash[id] = update;
                    }
                    else
                    {
                        string pair = Parser[i];
                        Parser2[0] = pair;
                        id         = Parser2[1];;
                        update     = Parser2[2];
                        hash[id]   = update;
                    }

                    if (id == "")
                    {
                        throw new ApplicationException("Bad evil. Container ID is empty string.");
                    }
                    if (update == "")
                    {
                        throw new ApplicationException("Bad evil. Update ID is empty string.");
                    }
                }
            }

            /*
             * add or overwrite a container update value
             */

            Parser2[0] = newStr;
            string id2     = Parser2[1];
            string update2 = Parser2[2];

            hash[id2] = update2;

            StringBuilder sb = new StringBuilder(hash.Count * 20);

            i = 0;
            foreach (string key in hash.Keys)
            {
                if (i > 0)
                {
                    sb.Append(",");
                }
                i++;

                string val = hash[key].ToString();
                if (key == "")
                {
                    throw new ApplicationException("Bad evil. Accumulator has empty string for key.");
                }
                if (val == "")
                {
                    throw new ApplicationException("Bad evil. Accumulator has empty string for value.");
                }
                sb.AppendFormat("{0}{1}{2}", key, Delimitor, val);
            }

            return(sb.ToString());
        }
示例#16
0
		/// <summary>
		/// Generates Device side implementation from SCPD XML
		/// </summary>
		/// <param name="ClassName">Class Name to build</param>
		/// <param name="ns">Namespace to use</param>
		/// <param name="SavePath">Path to save source</param>
		/// <param name="ServiceID">Service ID to use</param>
		/// <param name="ServiceURN">Service URN to use</param>
		/// <param name="SCPD_XML">SCPD XML String</param>
		public static void Generate(String ClassName, String ns, String SavePath, String ServiceID, String ServiceURN, String SCPD_XML)
		{
			UPnPService s = new UPnPService(1);
			DText p = new DText();
			p.ATTRMARK = ":";
			p[0] = ServiceURN;

			string v = p[p.DCOUNT()];
			s.SetVersion(v);
			s.ParseSCPD(SCPD_XML);
			String cl = "\r\n";
			
			StringBuilder cs = new StringBuilder();
			UPnPArgument[] Args;
			UPnPArgument arg;
			UPnPStateVariable[] SV = s.GetStateVariables();

			cs.Append("using Intel.UPNP;" + cl + cl);
			cs.Append("namespace " + ns + cl);
			cs.Append("{\r\n");
			cs.Append("    /// <summary>" + cl);
			cs.Append("    /// Transparent DeviceSide UPnP Service" + cl);
			cs.Append("    /// </summary>" + cl);
			cs.Append("    public class " + ClassName + " : IUPnPService" + cl);
			cs.Append("    {" + cl + cl);
			cs.Append("        // Place your declarations above this line\r\n");
			cs.Append("\r\n");
			cs.Append("        #region AutoGenerated Code Section [Do NOT Modify, unless you know what you're doing]\r\n");
			cs.Append("        //{{{{{ Begin Code Block\r\n");
			cs.Append("\r\n");
			cs.Append("        private _" + ClassName + " _S;\r\n");
			cs.Append("        public static string URN = \"" + ServiceURN + "\";\r\n");
			cs.Append("        public double VERSION\r\n");
			cs.Append("        {\r\n");
			cs.Append("           get\r\n");
			cs.Append("           {\r\n");
			cs.Append("               return(double.Parse(_S.GetUPnPService().Version));\r\n");
			cs.Append("           }\r\n");
			cs.Append("        }\r\n\r\n");

			// Build Enumerations
			Hashtable elist = BuildEnumerations(SV);
			IDictionaryEnumerator el = elist.GetEnumerator();
			VarData vd;
			while(el.MoveNext())
			{
				vd = (VarData)el.Value;
				cs.Append("        public enum Enum_" + vd.VariableName + "\r\n");
				cs.Append("        {\r\n");
				foreach(EnumStruct vs in vd.Enumerations)
				{
					cs.Append("            " + vs.EnumName + ",\r\n");
				}
				cs.Append("        }\r\n");

				cs.Append("        public Enum_" + vd.VariableName + " ");
				if(s.GetStateVariableObject(vd.VariableName).SendEvent==true)
				{
					cs.Append("Evented_");
				}
				cs.Append(vd.VariableName + "\r\n");
				cs.Append("        {\r\n");
				cs.Append("            set\r\n");
				cs.Append("            {\r\n");
				cs.Append("               string v = \"\";\r\n");
				cs.Append("               switch(value)\r\n");
				cs.Append("               {\r\n");
				foreach(EnumStruct vs in vd.Enumerations)
				{
					cs.Append("                  case Enum_" + vd.VariableName + "." + vs.EnumName + ":\r\n");
					cs.Append("                     v = \"" + vs.EnumValue + "\";\r\n");
					cs.Append("                     break;\r\n");
				}
				cs.Append("               }\r\n");
				cs.Append("               _S.SetStateVariable(\"" + vd.VariableName + "\",v);\r\n");
				cs.Append("            }\r\n");
				cs.Append("            get\r\n");
				cs.Append("            {\r\n");
				cs.Append("               Enum_" + vd.VariableName + " RetVal = 0;\r\n");
				cs.Append("               string v = (string)_S.GetStateVariable(\"" + vd.VariableName + "\");\r\n");
				cs.Append("               switch(v)\r\n");
				cs.Append("               {\r\n");
				foreach(EnumStruct vs in vd.Enumerations)
				{
					cs.Append("                  case \"" + vs.EnumValue + "\":\r\n");
					cs.Append("                     RetVal = Enum_" + vd.VariableName + "." + vs.EnumName + ";\r\n");
					cs.Append("                     break;\r\n");
				}
				cs.Append("               }\r\n");
				cs.Append("               return(RetVal);\r\n");
				cs.Append("           }\r\n");
				cs.Append("        }\r\n");
			}

			el.Reset();
			while(el.MoveNext())
			{
				vd = (VarData)el.Value;
				cs.Append("        static public string Enum_" + vd.VariableName + "_ToString(Enum_" + vd.VariableName + " en)\r\n");
				cs.Append("        {\r\n");
				cs.Append("            string RetVal = \"\";\r\n");
				cs.Append("            switch(en)\r\n");
				cs.Append("            {\r\n");
				foreach(EnumStruct vs in vd.Enumerations)
				{
					cs.Append("                case Enum_" + vd.VariableName + "." + vs.EnumName + ":\r\n");
					cs.Append("                    RetVal = \"" + vs.EnumValue + "\";\r\n");
					cs.Append("                    break;\r\n");
				}
				cs.Append("            }\r\n");
				cs.Append("            return(RetVal);\r\n");
				cs.Append("        }\r\n");

				// Build Easy Way to get All Values
				cs.Append("        static public string[] Values_" + vd.VariableName + "\r\n");
				cs.Append("        {\r\n");
				cs.Append("            get\r\n");
				cs.Append("            {\r\n");
				cs.Append("                string[] RetVal = new string[" + vd.Enumerations.Count.ToString() + "]{");
				string EasyStrings = "";
				foreach(EnumStruct vs in vd.Enumerations)
				{
					if(EasyStrings == "")
					{
						EasyStrings = "\"" + vs.EnumValue + "\"";
					}
					else
					{
						EasyStrings = "\"" + vs.EnumValue + "\"," + EasyStrings;
					}
				}
				cs.Append(EasyStrings + "};\r\n");
				cs.Append("                return(RetVal);\r\n");
				cs.Append("            }\r\n");
				cs.Append("        }\r\n");
			}

			cs.Append("        public delegate void OnStateVariableModifiedHandler(" + ClassName + " sender);\r\n");
			foreach(UPnPStateVariable V in SV)
			{
				cs.Append("        public event OnStateVariableModifiedHandler OnStateVariableModified_" + V.Name + ";\r\n");
			}
			
			foreach(UPnPStateVariable V in SV)
			{
				if(elist.ContainsKey(V.Name)==false)
				{
					// Build Accessors
					cs.Append("        public " + V.GetNetType().FullName + " ");
					if(V.SendEvent==true)
					{
						cs.Append("Evented_");
					}
					cs.Append(V.Name + "\r\n");
					cs.Append("        {\r\n");
					cs.Append("            get\r\n");
					cs.Append("            {\r\n");
					cs.Append("               return((" + V.GetNetType().FullName + ")_S.GetStateVariable(\"" + V.Name + "\"));\r\n");
					cs.Append("            }\r\n");
					cs.Append("            set\r\n");
					cs.Append("            {\r\n");
					cs.Append("               _S.SetStateVariable(\"" + V.Name + "\", value);\r\n");
					cs.Append("            }\r\n");
					cs.Append("        }\r\n");
				}
			}
			foreach(UPnPStateVariable V in SV)
			{
				cs.Append("        public UPnPModeratedStateVariable.IAccumulator Accumulator_");
				cs.Append(V.Name + "\r\n");
				cs.Append("        {\r\n");
				cs.Append("            get\r\n");
				cs.Append("            {\r\n");
				cs.Append("                 return(((UPnPModeratedStateVariable)_S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\")).Accumulator);\r\n");
				cs.Append("            }\r\n");
				cs.Append("            set\r\n");
				cs.Append("            {\r\n");
				cs.Append("                 ((UPnPModeratedStateVariable)_S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\")).Accumulator = value;\r\n");
				cs.Append("            }\r\n");
				cs.Append("        }\r\n");
				cs.Append("        public double ModerationDuration_" + V.Name + "\r\n");
				cs.Append("        {\r\n");
				cs.Append("            get\r\n");
				cs.Append("            {\r\n");
				cs.Append("                 return(((UPnPModeratedStateVariable)_S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\")).ModerationPeriod);\r\n");
				cs.Append("            }\r\n");
				cs.Append("            set\r\n");
				cs.Append("            {\r\n");
				cs.Append("                 ((UPnPModeratedStateVariable)_S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\")).ModerationPeriod = value;\r\n");
				cs.Append("            }\r\n");
				cs.Append("        }\r\n");
			}

			// Build MethodDelegates
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("        public delegate ");
				if(A.HasReturnValue==false)
				{
					cs.Append("void ");
				}
				else
				{
					cs.Append(A.GetRetArg().RelatedStateVar.GetNetType().FullName + " ");
				}
				cs.Append("Delegate_" + A.Name + "(");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						if(arg.Direction=="out")
						{
							cs.Append("out ");
						}
						if(arg.RelatedStateVar.AllowedStringValues==null)
						{
							cs.Append(arg.RelatedStateVar.GetNetType().FullName + " ");
						}
						else
						{
							cs.Append(ClassName + ".Enum_" + arg.RelatedStateVar.Name + " ");
						}
						cs.Append(arg.Name);
						if(i<Args.Length-1)
						{
							cs.Append(", ");
						}
					}
				}
				cs.Append(");\r\n");
			}

			// Build Overriding Delegates
			cs.Append("\r\n");
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("        public Delegate_" + A.Name + " External_" + A.Name + " = null;\r\n");
			}
			cs.Append("\r\n");

			// Build Ability to remove Optional State Variables
			foreach(UPnPStateVariable V in s.GetStateVariables())
			{
				cs.Append("        public void RemoveStateVariable_" + V.Name + "()\r\n");
				cs.Append("        {\r\n");
				cs.Append("            _S.GetUPnPService().RemoveStateVariable(_S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\"));\r\n");
				cs.Append("        }\r\n");
			}

			// Build Ability to remove Optional Actions
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("        public void RemoveAction_" + A.Name + "()\r\n");
				cs.Append("        {\r\n");
				cs.Append("             _S.GetUPnPService().RemoveMethod(\"" + A.Name + "\");\r\n");
				cs.Append("        }\r\n");
			}
			// Add Helper Methods
			cs.Append("        public System.Net.IPEndPoint GetCaller()\r\n");
			cs.Append("        {\r\n");
			cs.Append("             return(_S.GetUPnPService().GetCaller());\r\n");
			cs.Append("        }\r\n");
			cs.Append("        public System.Net.IPEndPoint GetReceiver()\r\n");
			cs.Append("        {\r\n");
			cs.Append("             return(_S.GetUPnPService().GetReceiver());\r\n");
			cs.Append("        }\r\n");
			cs.Append("\r\n");
											
			// Build Private Class
			cs.Append("        private class _" + ClassName + "\r\n");
			cs.Append("        {\r\n");
			cs.Append("            private " + ClassName + " Outer = null;\r\n");
			cs.Append("            private UPnPService S;\r\n");
			cs.Append("            internal _" + ClassName + "(" + ClassName + " n)\r\n");
			cs.Append("            {\r\n");
			cs.Append("                Outer = n;\r\n");
			cs.Append("                S = BuildUPnPService();\r\n");
			cs.Append("            }\r\n");
			cs.Append("            public UPnPService GetUPnPService()\r\n");
			cs.Append("            {\r\n");
			cs.Append("                return(S);\r\n");
			cs.Append("            }\r\n");
			cs.Append("            public void SetStateVariable(string VarName, object VarValue)\r\n");
			cs.Append("            {\r\n");
			cs.Append("               S.SetStateVariable(VarName,VarValue);\r\n");
			cs.Append("            }\r\n");
			cs.Append("            public object GetStateVariable(string VarName)\r\n");
			cs.Append("            {\r\n");
			cs.Append("               return(S.GetStateVariable(VarName));\r\n");
			cs.Append("            }\r\n");
			cs.Append("            protected UPnPService BuildUPnPService()\r\n");
			cs.Append("            {\r\n");
			cs.Append("                UPnPStateVariable[] RetVal = new UPnPStateVariable[" + SV.Length.ToString() + "];\r\n");
			for(int i=0;i<SV.Length;++i)
			{
				cs.Append("                RetVal[" + i.ToString() +"] = new UPnPModeratedStateVariable(\"" + SV[i].Name + "\", typeof(" + SV[i].GetNetType().FullName + "), " + SV[i].SendEvent.ToString().ToLower() + ");\r\n");
				
				if((SV[i].Maximum!=null)||
					(SV[i].Minimum!=null)||
					(SV[i].Step!=null))
				{
					cs.Append("                RetVal[" + i.ToString() +"].SetRange(");
					if(SV[i].Minimum==null)
					{
						cs.Append("null");
					}
					else
					{
						cs.Append("(" + SV[i].Minimum.GetType().FullName + ")(" + SV[i].Minimum.ToString() + ")");
					}
					cs.Append(",");

					if(SV[i].Maximum==null)
					{
						cs.Append("null");
					}
					else
					{
						cs.Append("(" + SV[i].Maximum.GetType().FullName + ")(" + SV[i].Maximum.ToString() + ")");
					}
					cs.Append(",");
					
					if(SV[i].Step==null)
					{
						cs.Append("null");
					}
					else
					{
						cs.Append("(" + SV[i].Step.GetType().FullName + ")" + SV[i].Step.ToString());
					}
					cs.Append(");\r\n");
				}
				
				if(SV[i].DefaultValue!=null)
				{
					cs.Append("                RetVal[" + i.ToString() + "].DefaultValue = UPnPService.CreateObjectInstance(typeof(" + SV[i].GetNetType().FullName + "),\"" + UPnPService.SerializeObjectInstance(SV[i].DefaultValue) + "\");\r\n");
					//cs.Append("                RetVal[" + i.ToString() + "].DefaultValue = (" + SV[i].GetNetType().FullName + ")(\"" + UPnPService.SerializeObjectInstance(SV[i].DefaultValue) + "\";\r\n");
				}
				if(SV[i].AllowedStringValues!=null)
				{
					cs.Append("                RetVal[" + i.ToString() + "].AllowedStringValues = new string[" +
						SV[i].AllowedStringValues.Length.ToString() + "]{");
					for(int ai=0;ai<SV[i].AllowedStringValues.Length;++ai)
					{
						cs.Append("\"" + SV[i].AllowedStringValues[ai] + "\"");
						if(ai<SV[i].AllowedStringValues.Length-1)
						{
							cs.Append(", ");
						}
					}
					cs.Append("};\r\n");
				}
				
				System.Collections.IList e = s.Actions;
				foreach(UPnPAction A in e)
				{
					foreach(UPnPArgument ag in A.ArgumentList)
					{
						if(ag.RelatedStateVar.Name==SV[i].Name)
						{
							cs.Append("                RetVal[" + i.ToString() + "].AddAssociation(\"" + A.Name + "\", \"" + ag.Name + "\");\r\n");
						}
					}
				}
			}
			// Build UPnPService
			cs.Append("\r\n");
			cs.Append("                UPnPService S = new UPnPService(" +
				s.Version + ", \"" + ServiceID + "\", \"" + ServiceURN + "\", true, this);\r\n");
			cs.Append("                for(int i=0;i<RetVal.Length;++i)\r\n");
			cs.Append("                {\r\n");
			cs.Append("                   S.AddStateVariable(RetVal[i]);\r\n");
			cs.Append("                }\r\n");
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("                S.AddMethod(\"" + A.Name + "\");\r\n");
			}

			cs.Append("                return(S);\r\n");
			cs.Append("            }\r\n\r\n");

			System.Collections.IList ee = s.Actions;
			foreach(UPnPAction A in ee)
			{
				if(A.HasReturnValue)
				{
					cs.Append("            [Intel.UPNP.ReturnArgument(\""+A.GetRetArg().Name+"\")]"+cl);
				}
				cs.Append("            public ");
				if(A.HasReturnValue==false)
				{
					cs.Append("void ");
				}
				else
				{
					cs.Append(A.GetRetArg().RelatedStateVar.GetNetType().FullName + " ");
				}

				cs.Append(A.Name+"(");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						if(arg.Direction=="out")
						{
							cs.Append("out ");
						}
						cs.Append(arg.RelatedStateVar.GetNetType().FullName + " ");
						cs.Append(arg.Name);
						if(i<Args.Length-1)
						{
							cs.Append(", ");
						}
					}
				}
				cs.Append(")" + cl);
				cs.Append("            {\r\n");

				// Convert to Enum if neccessary
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if((arg.IsReturnValue==false)&&
					(arg.RelatedStateVar.AllowedStringValues!=null))
					{
						cs.Append("                Enum_" + arg.RelatedStateVar.Name + " e_" + arg.Name + ";\r\n");
						if(arg.Direction=="in")
						{
							cs.Append("                switch(" + arg.Name + ")\r\n");
							cs.Append("                {\r\n");
							vd = (VarData)elist[arg.RelatedStateVar.Name];
							foreach(EnumStruct ss in vd.Enumerations)
							{
								cs.Append("                    case \"" + ss.EnumValue + "\":\r\n");
								cs.Append("                        e_" + arg.Name + " = Enum_" + arg.RelatedStateVar.Name + "." + ss.EnumName + ";\r\n");
								cs.Append("                        break;\r\n");
							}
							cs.Append("                    default:\r\n");
							cs.Append("                        e_" + arg.Name + " = 0;\r\n");
							cs.Append("                        break;\r\n");
							cs.Append("                }\r\n");
						
						}
					}
				}

				// Make Method Call
				if(A.HasReturnValue==true)
				{
					cs.Append("                object RetObj = null;\r\n");
				}
				cs.Append("                if(Outer.External_" + A.Name + " != null)\r\n");
				cs.Append("                {\r\n");
				cs.Append("                    ");
				if(A.HasReturnValue==true)
				{
					cs.Append("RetObj = ");
				}
				cs.Append("Outer.External_" + A.Name + "(");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						if(arg.Direction=="out")
						{
							cs.Append("out ");
						}
						if(arg.RelatedStateVar.AllowedStringValues!=null)
						{
							cs.Append("e_");
						}
						cs.Append(arg.Name);
						if(i<Args.Length-1)
						{
							cs.Append(", ");
						}
					}
				}
				cs.Append(");\r\n");
				cs.Append("                }\r\n");
				cs.Append("                else\r\n");
				cs.Append("                {\r\n");
				cs.Append("                    ");
				if(A.HasReturnValue==true)
				{
					cs.Append("RetObj = ");
				}
				cs.Append("Sink_" + A.Name + "(");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						if(arg.Direction=="out")
						{
							cs.Append("out ");
						}
						if(arg.RelatedStateVar.AllowedStringValues!=null)
						{
							cs.Append("e_");
						}
						cs.Append(arg.Name);
						if(i<Args.Length-1)
						{
							cs.Append(", ");
						}
					}
				}
				cs.Append(");\r\n");
				cs.Append("                }\r\n");

				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if((arg.IsReturnValue==false)&&
						(arg.RelatedStateVar.AllowedStringValues!=null))
					{
						if(arg.Direction=="out")
						{
							cs.Append("                switch(e_" + arg.Name + ")\r\n");
							cs.Append("                {\r\n");
							vd = (VarData)elist[arg.RelatedStateVar.Name];
							foreach(EnumStruct ss in vd.Enumerations)
							{
								cs.Append("                    case Enum_" + arg.RelatedStateVar.Name + "." + ss.EnumName + ":\r\n");
								cs.Append("                        " + arg.Name + " = \"" + ss.EnumValue  + "\";\r\n");
								cs.Append("                        break;\r\n");
							}
							cs.Append("                    default:\r\n");
							cs.Append("                        " + arg.Name + " = \"\";\r\n");
							cs.Append("                        break;\r\n");
							cs.Append("                }\r\n");
						
						}
					}
				}
								
				if(A.HasReturnValue==true)
				{
					cs.Append("                return((" + A.GetRetArg().RelatedStateVar.GetNetType().FullName + ")RetObj);\r\n");
				}
				cs.Append("            }\r\n");
			}

			cs.Append("\r\n");
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("            public Delegate_" + A.Name + " Sink_" + A.Name + ";\r\n");
			}
			cs.Append("        }\r\n"); // End of Private Class
			
			// Build Constructor
			cs.Append("        public " + ClassName + "()\r\n");
			cs.Append("        {\r\n");
			cs.Append("            _S = new _" + ClassName + "(this);\r\n");
			foreach(UPnPStateVariable V in SV)
			{
				cs.Append("            _S.GetUPnPService().GetStateVariableObject(\"" + V.Name + "\").OnModified += new UPnPStateVariable.ModifiedHandler(OnModifiedSink_" + V.Name + ");\r\n");
			}
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("            _S.Sink_" + A.Name + " = new Delegate_" + A.Name + "(" + A.Name + ");\r\n");
			}


			cs.Append("        }\r\n");
			cs.Append("        public " + ClassName + "(string ID):this()\r\n");
			cs.Append("        {\r\n");
			cs.Append("            _S.GetUPnPService().ServiceID = ID;\r\n");
			cs.Append("        }\r\n");
			cs.Append("        public UPnPService GetUPnPService()\r\n");
			cs.Append("        {\r\n");
			cs.Append("            return(_S.GetUPnPService());\r\n");
			cs.Append("        }\r\n");
			foreach(UPnPStateVariable V in SV)
			{
				cs.Append("        private void OnModifiedSink_" + V.Name + "(UPnPStateVariable sender, object NewValue)\r\n");
				cs.Append("        {\r\n");
				cs.Append("            if(OnStateVariableModified_" + V.Name + " != null) OnStateVariableModified_" + V.Name + "(this);\r\n");
				cs.Append("        }\r\n");
			}
			cs.Append("        //}}}}} End of Code Block\r\n\r\n");
			cs.Append("        #endregion\r\n");
			cs.Append("\r\n");
			
			foreach(UPnPAction A in s.Actions)
			{
				cs.Append("        /// <summary>\r\n");
				cs.Append("        /// Action: " + A.Name + "\r\n"); 
				cs.Append("        /// </summary>\r\n");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						        cs.Append("        /// <param name=\"" + arg.Name + "\">Associated State Variable: " + arg.RelatedStateVar.Name + "</param>\r\n");
					}
				}
				if(A.HasReturnValue==true)
				{
					cs.Append("        /// <returns>Associated StateVariable: " + A.GetRetArg().RelatedStateVar.Name + "</returns>\r\n");
				}
				cs.Append("        public ");
				if(A.HasReturnValue==false)
				{
					cs.Append("void ");
				}
				else
				{
					cs.Append(A.GetRetArg().RelatedStateVar.GetNetType().FullName + " ");
				}

				cs.Append(A.Name+"(");
				Args = A.ArgumentList;
				for(int i=0;i<Args.Length;++i)
				{
					arg = Args[i];
					if(arg.IsReturnValue==false)
					{
						if(arg.Direction=="out")
						{
							cs.Append("out ");
						}

						if(arg.RelatedStateVar.AllowedStringValues!=null)
						{
							cs.Append("Enum_" + arg.RelatedStateVar.Name + " ");
						}
						else
						{
							cs.Append(arg.RelatedStateVar.GetNetType().FullName + " ");
						}
						cs.Append(arg.Name);
						if(i<Args.Length-1)
						{
							cs.Append(", ");
						}
					}
				}
				cs.Append(")" + cl);
				cs.Append("        {\r\n");
				cs.Append("            //ToDo: Add Your implementation here, and remove exception\r\n");
				cs.Append("            throw(new UPnPCustomException(800,\"This method has not been completely implemented...\"));\r\n");
				cs.Append("        }\r\n");
			}


			cs.Append("    }\r\n");
			cs.Append("}");
			
			UTF8Encoding UTF8 = new UTF8Encoding();
			FileStream ws = new FileStream(SavePath, FileMode.Create, FileAccess.Write);
			byte[] buffer = UTF8.GetBytes(cs.ToString());
			ws.Write(buffer,0,buffer.Length);
			ws.Close();
		}
        private bool PrepareForConnectionTest_SINK(string ProtocolInfoString)
        {
            DText parser = new DText();
            bool  Found  = false;

            parser.ATTRMARK = ",";
            bool RetVal = true;
            int  ConnID = 0, AVTID = 0, RcsID = 0;

            Ev.Reset();
            CM.OnStateVariable_CurrentConnectionIDs += new CpConnectionManager.StateVariableModifiedHandler_CurrentConnectionIDs(CurrentConnectionIDs_P4C);

            StartCountDown(CurrentTime, TotalTime);
            try
            {
                CM.Sync_PrepareForConnection(ProtocolInfoString, "/", -1, CpConnectionManager.Enum_A_ARG_TYPE_Direction.INPUT, out ConnID, out AVTID, out RcsID);
            }
            catch (UPnPInvokeException)
            {
                AddEvent(LogImportance.Critical, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection could not be created");
                RetVal = false;
            }
            AbortCountDown();
            CurrentTime += 30;

            if (RetVal)
            {
                StartCountDown(CurrentTime, TotalTime);
                if (Ev.WaitOne(30000, false))
                {
                    AbortCountDown();
                    CurrentTime += 30;

                    // Check if evented correctly
                    parser[0] = CM.CurrentConnectionIDs;
                    Found     = false;
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (int.Parse(parser[i]) == ConnID)
                        {
                            Found = true;
                            break;
                        }
                    }
                    if (Found)
                    {
                        // Event OK
                        Ev.Reset();

                        StartCountDown(CurrentTime, TotalTime);
                        try
                        {
                            CM.Sync_ConnectionComplete(ConnID);
                        }
                        catch (UPnPInvokeException)
                        {
                            AddEvent(LogImportance.Critical, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection could not be closed");
                            RetVal = false;
                        }
                        AbortCountDown();
                        CurrentTime += 30;

                        if (RetVal)
                        {
                            StartCountDown(CurrentTime, TotalTime);
                            if (Ev.WaitOne(30000, false))
                            {
                                AddEvent(LogImportance.Remark, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection Handling OK");
                            }
                            else
                            {
                                AddEvent(LogImportance.Critical, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection Created/Evented, but CLOSE did not produce events");
                                RetVal = false;
                            }
                            AbortCountDown();
                            CurrentTime += 30;
                        }
                    }
                    else
                    {
                        CurrentTime += 30;
                        // Event not found, FAIL
                        AddEvent(LogImportance.Critical, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection Created, but event failed");
                        RetVal = false;
                    }
                }
                else
                {
                    CurrentTime += 30;
                    // Failed to send event
                    AddEvent(LogImportance.Critical, "Connection Handling", "   Sink Protocol Info [" + ProtocolInfoString + "] Connection Created, but event missing");
                    RetVal = false;
                }
            }
            CM.OnStateVariable_CurrentConnectionIDs -= new CpConnectionManager.StateVariableModifiedHandler_CurrentConnectionIDs(CurrentConnectionIDs_P4C);
            return(RetVal);
        }