/// <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; } } }
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)); }
/// <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(); }
/// <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(); } }
/// <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()); }
/// <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); }