Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C# AVTransport and RenderingControl Device
19-08-2013, 09:33 PM (This post was last modified: 19-08-2013 11:23 PM by ACDN.)
Post: #1
C# AVTransport and RenderingControl Device
Hi!

I am attempting to create a UPNP device that will offer AVTransport and RenderingControl services. After reading the overview documentation, other posts on the forum and parts of the API documentation I feel that I am getting close. Though as you'll see in the code, I don't know what the UPNP type should be. Though this is a side issue. Right now I am getting the following error when calling SetEnabled on my device object.

Error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I've attached my vs2010 project. It is a simple single form win32 application. In addition I've posted the code behind the form below.

Any help or guidance would be greatly appreciated.

ACDN


Code:
public partial class Form1 : Form
    {
        /// <summary>
        /// UPNP Library
        /// </summary>
        private Library lib { get; set; }

        //Our UPNP device
        private DvDeviceStandard device { get; set; }

        //Our AV Transport
        public AvTransportProvider avTransport1 { get; set; }

        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            StartDevice();
        }

        private void StartDevice()
        {

            try
            {

                OpenHome.Net.Core.InitParams initParams = new InitParams();

                // initParams defaults to useful values for all fields but you can optionally
                //change any values here

                lib = OpenHome.Net.Core.Library.Create(initParams);

                //SubnetList subnetList = new SubnetList();
                //NetworkAdapter nif = subnetList.SubnetAt(0);
                //uint subnet = nif.Subnet();
                //subnetList.Dispose();

                lib.StartDv();

                //Create Device

                string udn = GenerateGloballyUniqueIdentifier();
                device = new DvDeviceStandard(udn);

                device.SetAttribute("Upnp.Domain", "openhome.org");
                device.SetAttribute("Upnp.Type", "????");
                device.SetAttribute("Upnp.Friendly", "ohNet Device");
                device.SetAttribute("Upnp.Manufacturer", "Customware");
                device.SetAttribute("Upnp.ModelName", "ohNet Device");

                //Init providers
                avTransport1 = new AvTransportProvider(device);

                device.SetEnabled();

            }
            catch (Exception ex)
            {
        
                Console.WriteLine("An error occurred in starting device.  Error: " + ex.ToString());
                              
            }
        }

        private string GenerateGloballyUniqueIdentifier()
        {
            Guid id = Guid.NewGuid();

            Console.WriteLine(id);  

            return id.ToString();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {

            if (device != null)
                device.Dispose();

            if (lib != null)
                lib.Dispose();
        }              
    }

    /// <summary>
    /// AV Transport Provider
    /// </summary>
    public class AvTransportProvider : DvProviderUpnpOrgAVTransport1
    {
        
        public AvTransportProvider(DvDevice aDevice)
            : base(aDevice)
        {
            EnableActionSetAVTransportURI();
            EnableActionSetNextAVTransportURI();
            EnableActionPlay();
            EnableActionStop();
            EnableActionNext();
            EnableActionGetTransportInfo();
            EnableActionGetPositionInfo();
            EnableActionGetMediaInfo();
            EnableActionGetDeviceCapabilities();
            EnableActionGetCurrentTransportActions();
        }

        
    }



UPDATED


Well, it never fails which is why I do it. After posting to a forum for help I keep trying things and get past my road block.

In this case the memory error went away when I set this attribute.

Code:
device.SetAttribute("Upnp.Version", "1");

Not sure why, but at least I can keep going.

Still interested in finding out what the correct setting for the attribute: Upnp.Type should be.

UPDATED

The correct type is: MediaRenderer

I am sure that I will have more questions as I continue work on this project.


Attached File(s)
.zip  OhNetDevice.zip (Size: 430.82 KB / Downloads: 27)
Find all posts by this user
19-08-2013, 11:16 PM (This post was last modified: 19-08-2013 11:21 PM by ACDN.)
Post: #2
RE: C# AVTransport and RenderingControl Device
Next Road Block.

Getting the message from Proxy Error: 404: Not Found when calling GetProtocolInfo on my devices connection manager service.

Here is some further context:

Using my control point application I can detect the C# device on the network. Which I've named: MyOhNetDevice

udn = a51c656e-9d38-4ab0-9d5c-5067627c6637
location = http://10.0.3.130:60260/a51c656e-9d38-4a...device.xml
name = MyOhNetDevice

Here is the XML on my device so far:

Code:
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>1</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
<friendlyName>MyOhNetDevice</friendlyName>
<manufacturer>Customware</manufacturer>
<modelName>ohNet Device</modelName>
<UDN>uuid:a51c656e-9d38-4ab0-9d5c-5067627c6637</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
<serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
<SCPDURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/Upnp/upnp.org-AVTransport-1/service.xml
</SCPDURL>
<controlURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/upnp.org-AVTransport-1/control
</controlURL>
<eventSubURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/upnp.org-AVTransport-1/event
</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<SCPDURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/Upnp/upnp.org-ConnectionManager-1/service.xml
</SCPDURL>
<controlURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/upnp.org-ConnectionManager-1/control
</controlURL>
<eventSubURL>
/a51c656e-9d38-4ab0-9d5c-5067627c6637/upnp.org-ConnectionManager-1/event
</eventSubURL>
</service>
</serviceList>
</device>
</root>

This is great, my device is visible to UPNP detection!

After my control point detects UPNP devices it attempts to communicate with it's connection manager to determine it;s protocols. It is at this point when I attempt to communicate with the connection manager on my device that I get the error: 404-Not Found.

Here is some code, which works for other UPNP devices on my network:

Code:
Console.Write("\n\nSync call to device " + aDevice.Udn() + "\n");
            OpenHome.Net.ControlPoint.Proxies.CpProxyUpnpOrgConnectionManager1 connMgr = new OpenHome.Net.ControlPoint.Proxies.CpProxyUpnpOrgConnectionManager1(aDevice);
            bool bAssigned = false;
            try
            {
                string source;
                string sink;
                connMgr.SyncGetProtocolInfo(out source, out sink);
                Console.Write("source is " + source + "\nsink is " + sink + "\n");
            }
           catch (OpenHome.Net.ControlPoint.ProxyError)
            {
                Console.WriteLine("...failed.  (This may be expected but shouldn't be easily reproducible.)");
            }

The exception is trigger on the line calling GetProtocolInfo

Any ideas as to why this might be happening?
Find all posts by this user
20-08-2013, 02:30 AM
Post: #3
RE: C# AVTransport and RenderingControl Device
ROAD BLOCK RESOLVED

Apparently error 404: Not Found isn't entirely accurate. If I was paying attention to the output window of visual studio in my device project I would have seen this.

WARNING: unexpected exception OpenHome.Net.Device.ActionDisabledError("Exception of type 'OpenHome.Net.Device.ActionDisabledError' was thrown.")

After diving into the source code, (gotta love open source) I was able to determine that none of these methods are implemented.

The code below is the stub for get protocol info in the source.

Code:
/// <summary>
        /// GetProtocolInfo action.
        /// </summary>
        /// <remarks>Will be called when the device stack receives an invocation of the
        /// GetProtocolInfo action for the owning device.
        ///
        /// Must be implemented iff EnableActionGetProtocolInfo was called.</remarks>
        /// <param name="aInvocation">Interface allowing querying of aspects of this particular action invocation.</param>
        /// <param name="aSource"></param>
        /// <param name="aSink"></param>
        protected virtual void GetProtocolInfo(IDvInvocation aInvocation, out string aSource, out string aSink)
        {
            throw (new ActionDisabledError());
        }

This is all good, now I can start moving forward again.

This whole conversation feels a little one sided at the moment... Smile
Find all posts by this user
20-08-2013, 07:46 AM (This post was last modified: 20-08-2013 07:47 AM by simonc.)
Post: #4
RE: C# AVTransport and RenderingControl Device
(19-08-2013 09:33 PM)ACDN Wrote:  I've attached my vs2010 project. It is a simple single form win32 application. In addition I've posted the code behind the form below.

Thanks for doing this. Its a great way to make sure we understand the issues you're encountering and makes it really easy to provide feedback. Or it would do if you didn't beat me to it and answer all your own questions Smile

(19-08-2013 09:33 PM)ACDN Wrote:  Well, it never fails which is why I do it. After posting to a forum for help I keep trying things and get past my road block.

In this case the memory error went away when I set this attribute.

Code:
device.SetAttribute("Upnp.Version", "1");

Not sure why, but at least I can keep going.
This attribute is a mandatory part of the device xml file and is required for SSDP advertisements and responses. There are a total of 6 mandatory attributes for UPnP devices; you'd covered the other 5 in your initial code.

The error you got when you forgot to set the Version attribute wasn't terribly helpful. I've posted a bug about this but it might be a while before we can address it.
Find all posts by this user
20-08-2013, 07:56 AM
Post: #5
RE: C# AVTransport and RenderingControl Device
(20-08-2013 02:30 AM)ACDN Wrote:  Apparently error 404: Not Found isn't entirely accurate. If I was paying attention to the output window of visual studio in my device project I would have seen this.

WARNING: unexpected exception OpenHome.Net.Device.ActionDisabledError("Exception of type 'OpenHome.Net.Device.ActionDisabledError' was thrown.")

After diving into the source code, (gotta love open source) I was able to determine that none of these methods are implemented.

Each time you call EnableAction[action_name]() in your provider's constructor you should also override the virtual function [action_name].

I spotted one other potential issue in your code. You also need to enable which evented state variables are supported. For AVTransport, you should also call EnablePropertyLastChange() in your Provider's constructor. Its best practice to do this before you enable any actions. Note that you also need to initialise the property before SetEnabled() is called on the containing device.
Find all posts by this user
21-08-2013, 02:53 AM
Post: #6
RE: C# AVTransport and RenderingControl Device
Hey Simonc!

Thanks for the detailed replies. I am sure this thread will be useful to others.

Good point on calling EnablePropertyLastChange() first in my AVTransport constructor. What is an acceptable initial value for this property? I thought it would get set on it own when a property changes.

I am pretty sure I know the answer to my next question but I thought I would ask it anyways. Is there any functionality in the device library for outputting the media? For example, playing the audio or displaying the video? I haven't seen anything so I've been researching other libraries to handle it.

Keep up the great work!

ACDN

PS: When I am farther along I will post my project in the hopes it will help others.
Find all posts by this user
21-08-2013, 08:40 AM
Post: #7
RE: C# AVTransport and RenderingControl Device
(21-08-2013 02:53 AM)ACDN Wrote:  Good point on calling EnablePropertyLastChange() first in my AVTransport constructor. What is an acceptable initial value for this property? I thought it would get set on it own when a property changes.

ohNet will be happy that you just initialise the property. Any value, including an empty string "" will do. The UPnP forum's description for LastChange is quite a bit more prescriptive - it'll expect xml describing all the other (non-evented) state variables in the service.

(21-08-2013 02:53 AM)ACDN Wrote:  I am pretty sure I know the answer to my next question but I thought I would ask it anyways. Is there any functionality in the device library for outputting the media? For example, playing the audio or displaying the video? I haven't seen anything so I've been researching other libraries to handle it.

Its the answer you expected/feared I'm afraid. ohNet is a UPnP stack and does not include implementations of MediaRenderer or any other standard device types.
Find all posts by this user
21-08-2013, 04:53 PM
Post: #8
RE: C# AVTransport and RenderingControl Device
Simonc,

That is a perfectly acceptable answer. Your library works great for what it needs to do. I've already come across a few solutions to outputting the media. Now it will be matter of wiring it all up to work as expected based on the different actions in the providers.

Looking good so far Smile

ACDN
Find all posts by this user
07-10-2013, 02:57 AM
Post: #9
RE: C# AVTransport and RenderingControl Device
Thanks very much for your detailed description. Can you please upload the up-to-date version of your project?
Find all posts by this user


Forum Jump: