Getting started with DPWS in the .NET Micro Framework


The .NET Micro Framework v3.0 includes a full-featured DPWS stack and a code generation tool, MFSvcUtil.exe, that generates Hosted Service Stubs and Client Proxies from a standard WSDL.


The DPWS stack on the Micro Framework has been developed exclusively for the Micro Framework, and will not run on a Windows platform unless you are running it in the Micro Framework emulator.


There are a number of different configurations you can experiment with:


1)      Running a hosted service on a Micro Framework device together with one of the following :


a.       A  Micro Framework DPWS client in the Micro Framework emulator


b.      A Micro Framework DPWS client on a second Micro Framework device. This can actually be the same device that the Hosted Service is running on, but that doesn’t make a lot of sense outside of testing.


c.        A WSDAPI client on a Widows computer or a WinCE device


d.      A .NET 3.0 Windows Communication Foundation (WCF) client on a Windows computer. In this configuration, Discovery does not work.  Discovery is expected to be added to WCF in a future release.


2)      Running a Micro Framework DPWS client on a Micro Framework device and:


a.       A Micro Framework Hosted Service in the Micro Framework Emulator


b.      A  WSDAPI Service running on Windows or a Win CE device


c.       A WCF Service running on a Windows Computer.


I’ll try to cover the relevant points for each of these scenarios. The DPWS solution I am using is the solution included with the SDK.  This sample was built using the SimpleService WSDL (http://msdn.microsoft.com/en-us/library/cc264253.aspx   Part of the WHQL certification test suite) and the MFSvcUtil code generation tool.


 


Scenario 1a.


This is a great scenario for getting the Micro Framework samples running, and for exploring the way the DPWS stack on the Micro Framework works.  To set up this scenario, you will need the following:


1)      A Micro Framework device with Networking. You can use the GHI Embedded Master or the Device Solutions Tahoe2 board.


2)      A Windows Computer with the following installed:


a.       Visual Studio 2008 SP1 (Express Edition is OK)


b.      .NET Micro Framework V3.0 SDK


c.       A network subnet set up between the device and the computer.  My network set up is as follows:


                                                               i.      An Allied Telesyn AT-GS900/8 10/100/1000 Ethernet switch (Any hub should work)


                                                             ii.      The MF Device and the PC are the only things connected to the switch (plus power, of course)


                                                            iii.      The Device IP configuration is


1.       Addr = 10.1.1.102


2.       Subnet Mask = 255.255.255.0


3.       Gateway 10.1.1.102


4.       DNS = 0.0.0.0


5.       DHCP is disabled


                                                           iv.      The PC TCP/IP configuration is:


1.       IP = 10.1.1.104


2.       Everything else is the same as the device configuration. Make sure you use the Static IP option


3.       Make sure IPSec is not enabled


3)      On the PC, navigate to My Documents\Microsoft .NET Micro Framework 3.0\Samples\DPWS and open the DPWS solution. This solution will load both the Micro Framework DPWS Hosted Service project and the Micro Framework DPWS Client. Make sure you start VS with elevated permissions (Run as administrator)


4)      Connect the device to the PC


I am going to set up the solution to run the client in the emulator when I press F5, and to deploy the service to the device when I right click on the Service project, select “Debug” and then select “Start a new instance” My device is attached to COM 9. Also, I have modified both the Service and Client projects slightly to help decipher the Debug output.  I added “SERVICE:” to all the debug prints in the Service project and “CLIENT:” to all the debug prints in the client project. This helps later to ascertain where a particular message is coming from.


1)      On the main tool bar in VS, Select Build/Configuration Manager


a.       Make sure the build box is selected for both projects, and the deploy box is checked for the client project and not for the service project


b.      Close the dialog


2)      Right Click on the Client project in the Solution Explorer and select Properties


a.       Select the Micro Framework Tab and set the transport to Emulator and the Device to Microsoft Emulator


3)      Back in the Solution Explorer, right click on the Service project and select Properties


a.       Set the Transport and device to match your device, Serial and COM9 in my case


Now, when you hit F5 the Client will start up in the emulator. You can minimize the emulator UI since it is not used in this example. The VS Output window will let you know what the client is doing.


With the client running, Right click on the Server project in the Solution Wizard, and select “Debug/Start a new instance. This will cause the service to be deployed to the device and started.  Then sit back and watch the client discover and exercise the service. At this point, you can set breakpoints in either project and debug as expected.


 


 


Scenario 1b:


This scenario is very similar to the previous scenario 1a.  About the only difference is that you set the Client properties to deploy to a device rather than the Emulator. 


Scenario 1c:


This Scenario requires that you have a WSDAPI client. It is beyond the scope of this article to describe how to build a WSDAPI client, but you can use the WSDAPI tool SvcUtil.EXE and the SimpleService WSDL to generate your stubs and proxies. There is lots of information about how to do this on the Microsoft.com site.


 


Scenario 1d: (Please see attached Visual Studio Solution Zip file for source )


This scenario is a little more challenging, since WCF does not currently support WS-Discovery. It is necessary to tell the client the endpoint address of the Service, and then all should work well. Visual Studio supports generating the necessary WCF stubs and proxies for the WCF client from the WSDL. It will also generate a configuration XML file with the same name as the client. In my case, the app is called:


WCFSimpleServiceApp.Exe  (this one lists as an application)


and the configuration file is called:


WCFSimpleServiceApp.Exe (This one is listed as an XML Configuration file).


There is a client section near the bottom of this file. When you first see it, it will probable refer to localhost. You need to change three locations to point to the IP address of your device. In this file, the IP address is  192.168.0.3. The WCF client will use this configuration file to locate and connect with the Micro Framework service running on your device.


 


The contents of the file are:


 


?xml version="1.0" encoding="utf-8"?>


<configuration>


  <system.serviceModel>


    <bindings>


      <customBinding>


        <binding name="SimpleServiceSoapBinding">


         


          <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"


              messageVersion="Soap12WSAddressingAugust2004" writeEncoding="utf-8">


            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"


                maxBytesPerRead="4096" maxNameTableCharCount="16384" />


          </textMessageEncoding>


          <httpTransport manualAddressing="false" maxBufferPoolSize="524288"


              maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"


              bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"


              keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"


              realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"


              useDefaultWebProxy="true" />


        </binding>


      </customBinding>


    </bindings>


  


 


 


    <client>


      <endpoint address="http://192.168.0.3:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b90" binding="customBinding"


          bindingConfiguration="SimpleServiceSoapBinding" contract="SimpleService"


          name="SimpleServicePort" />


      <endpoint address="http://192.168.0.3:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b91" binding="customBinding"


          bindingConfiguration="SimpleServiceSoapBinding" contract="EventSource"


          name="EventSourcePort" />


      <endpoint address="http://192.168.0.3:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b91" binding="customBinding"


          bindingConfiguration="SimpleServiceSoapBinding" contract="SubscriptionManager"


          name="SubscriptionManagerPort" />


    </client>


 


 


 


  </system.serviceModel>


</configuration>


 









Scenario 2a


Scenario 2a is very similar to scenario 1a, with the only change being where you instruct the project to deploy to. In this scenario, you set the client to deploy to the device and the service to deploy to the emulator. Everything else is the same.


 


Scenario 2b:


This scenario is the same as 1b, Make sure to start the client first, and then the service. As written, the Service sends a “Hello” and the client must be listening for it. Discovery can work both ways. However, Client initiated discovery is just not implemented in this sample.


 


Scenario 2c:


WCF does not currently support WS-Discovery required for Micro Framework clients to discover and query WCF services. This is being addressed in two ways:


1)      WS-Discovery will be supported in WCF in the .NET Framework 4.0


2)      We are investigating implementing the WS-Discovery Remote Extensions proposal.


 


Jim Mateer
Program Manager
 


 

WCFSimpleServiceProxy.zip

Comments (12)

  1. gert says:

    hi great article

    did you can post the source code of scenario 1d?

    thx

  2. The .NET Micro Framework v3.0 includes a full-featured DPWS stack and a code generation tool, MFSvcUtil.exe,

  3. Colin Miller says:

    Gert - There is a link to the source right after the scenario title.

  4. gert says:

    tried the sample, but i get a ws fault exception ...

  5. gert says:

    i get the following exception:

    A first chance exception of type 'System.ServiceModel.ProtocolException' occurred in mscorlib.dll

    another thing:

    my dpws service runs on enpoint:

    3cb0d1ba-cc3a-46ce-b416-212ac2419b51

    your sample addresses endpoint:

    3cb0d1ba-cc3a-46ce-b416-212ac2419b90

    is your mf dpws serivce sample ohter than the sample from the mf 3.0 sdk installation ?

  6. Colin Miller says:

    Micro Framework DPWS FAQ

    I recently posted a step by step guide to getting a DPWS service up and running on your device. Since then, I have received a few questions about how the Micro Framework DPWS works, and using it with WCF client apps. This document is intended to address some of those issues.

    Question 1: What is the expected workflow for creating a DPWS service, installing it on a device, and using it:

    Answer: This is really a great question that I probably should have addressed in the first article. Since I didn’t address it then, I’ll do that now.  The Micro Framework DPWS stack, like most Web Services, works best with a “Contract First” approach. Your first step should be to create or obtain a WSDL, a Web Services Description Language document that describes the contract between the services you’ll be running on the device, and the clients that will use these services.  “ Contract” is a weighty term that simply describes the methods that will be exposed, along with the parameters that it expects to receive and return (if any). The WSDL spec can be found here: http://www.w3.org/TR/wsdl. It is common practice to start with an existing WSDL that is similar to what you need, and modify it to meet your requirements.

    Once you have the WSDL, you feed it into the MFSvcUtil tool (in the tools directory of the Micro Framework SDK). The tool will generate the Micro Framework Service Stubs and a Micro Framework client Proxy from your WSDL. Then, assuming you are creating hosted services on the device, and not a client, you will copy the generated hosted service stub files into your project, instantiate classes derived from the generated interfaces, and flesh out the methods with whatever you want your service to do.

    You can then use the same WSDL to generate a WCF client proxy that matches your service. The tool to do this is called SvcUtil.exe and is available in the Windows SDK. The Proxy provides all the tools you need to communicate with your service. Throw a little UI around it and you’ll have a functioning service and client.

    Question 2:  What are these URN: UUID things and should I be concerned with them?

    Answer:  These are endpoints. Most of the ones you’ll see have the form :

    Urn:uuid:GUID, such as:

    urn:uuid:1496eeb2-373e-484b-8497-60ced1a5c4cb

    You may also see them in the form:

    http://localhost:8084/1496eeb2-373e-484b-8497-60ced1a5c4cb

    or

    http://192.23.24.103:8084/1496eeb2-373e-484b-8497-60ced1a5c4cb

    These all describe the endpoints of either one of the services running on the device, or the replyTo address of the client requesting a particular service. The endpoints use a GUID to ensure they will be unique. The important thing here is to make sure your client is asking for the appropriate urn:uuid in its requests. This is pretty automatic when using Discovery, but as I pointed out in the previous article, since WCF does not currently support Discovery, you have to give your WCF client these endpoints explicitly.  The important thing to remember is to make sure the endpoints your client is attempting to connect to are the actual endpoints of your services.

    Eventing example: This is a snippet oc code from the MVSvcUtil generated Eventing code, EventingServiceHostedService.cs:

    // Set base service properties

    ServiceNamespace = new WsXmlNamespace("eve", "http://schemas.example.org/EventingService&quot;);

    ServiceID = "urn:uuid:dfdff598-8081-4a9d-a8ce-4807e87b9b9b";

    ServiceTypeName = "EventingService";

    Here is a snippet from the WCF App. Config file:

      <client>

         <endpoint address="http://localhost:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b90&quot; binding="customBinding"

             bindingConfiguration="SimpleServiceSoapBinding" contract="SimpleService"

             name="SimpleServicePort" />

         <endpoint address="http://localhost:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b91&quot; binding="customBinding"

             bindingConfiguration="SimpleServiceSoapBinding" contract="EventSource"

             name="EventSourcePort" />

         <endpoint address="http://localhost:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b91&quot; binding="customBinding"

             bindingConfiguration="SimpleServiceSoapBinding" contract="SubscriptionManager"

             name="SubscriptionManagerPort" />

       </client>

    To make this client work with a service running on your device, you will need to modify the endpoint addresses to match your device IP address, and change either the device GUIDs or the client’s GUIDs to match.  In the current MF DPWS stack, each service must have its own endpoint. In future releases, all services running on a device will be able to share the same endpoint.

    Question 3: I have the SimpleService sample running, with a WCF Client. I am hitting an exception when trying to Subscribe to events.

    Answer:  There is a bug in the stack that does not properly handle the EndTo address. If you look at an example Soap envelope from a WCF Client to a MF Service below, you will see the EndTo section is malformed.  The easiest way to work around this is to modify your WCF client to send an appropriate EndTo address .  In the WsdEventingClient.CS file, locate where the subscription.EndTo.Address.Value= GetLocalIP() +”/EventSink”; line of code. It should be around line 122. Change it so the EndTo address is the same as the NotifyTo address:

    subscription.EndTo.Address.Value = subscription.Delivery.NotifyTo.Address.Value;

    This will be fixed in a later release of the stack.

    Question 4: I have the Simple Service sample running and can connect to it with a WCF client. When I try a “OneWay” request, I hit an exception

    Answer:  This is caused by WCF injecting a section into the Soap envelope that confuses the stack. The following is a good soap request, followed by a bad soap request, see the difference?

    GOOD soap envelope

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope&quot; xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"&gt;

     <s:Header>

       <a:Action s:mustUnderstand="1">http://schemas.example.org/SimpleService/OneWay</a:Action>">http://schemas.example.org/SimpleService/OneWay</a:Action>

       <a:From>

         <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address&gt;

       </a:From>

       <a:ReplyTo>

         <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address&gt;

       </a:ReplyTo>

       <a:MessageID>urn:uuid:810c6e77-aae7-423b-a888-9c4eb22481c8</a:MessageID>

       <a:To s:mustUnderstand="1">http://10.1.1.101:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b90</a:To&gt;

     </s:Header>

     <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

       <OneWay xmlns="http://schemas.example.org/SimpleService"&gt;

         <Param>1</Param>

       </OneWay>

     </s:Body>

    </s:Envelope>

    BAD soap enevelope

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope&quot; xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"&gt;

     <s:Header>

       <a:Action s:mustUnderstand="1">http://schemas.example.org/SimpleService/OneWay</a:Action>">http://schemas.example.org/SimpleService/OneWay</a:Action>

       <a:From>

         <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address&gt;

       </a:From>

       <a:ReplyTo>

         <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address&gt;

       </a:ReplyTo>

       <a:MessageID>urn:uuid:282e035c-fb43-4750-b9e6-3c3a6ad6bbbd</a:MessageID>

       <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPoxZoXC7r+opJsf1BMN+t5RAAAAAAQsSDzxG2XkGZ4g7AM7yjW4Ue1M+sdH5MprOgmAzDENcACQAA</VsDebuggerCausalityData&gt;

       <a:To s:mustUnderstand="1">http://10.1.1.101:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b90</a:To&gt;

     </s:Header>

     <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

       <OneWay xmlns="http://schemas.example.org/SimpleService"&gt;

         <Param>2</Param>

       </OneWay>

     </s:Body>

    </s:Envelope>

    ***Request Debug timer started

    Action: http://schemas.example.org/SimpleService/OneWay

    #### Exception System.Xml.XmlException - 0x00000000 (23) ####

    #### Ws.Services.Serialization.DataContractSerializer::ReadElement [IP: 0065] ####

    #### Ws.Services.Serialization.DataContractSerializer::IsParentStartElement [IP: 000c] ####

    #### schemas.example.org.SimpleService.OneWayDataContractSerializer::ReadObject [IP: 000a] ####

    #### schemas.example.org.SimpleService.SimpleService::OneWay [IP: 0010] ####

    #### System.Reflection.MethodBase::Invoke [IP: 0000] ####

    #### Dpws.Device.Services.DpwsHostedService::ProcessRequest [IP: 0081] ####

    #### Dpws.Device.Services.DpwsHostedService::Ws.Services.IWsServiceEndpoint.ProcessRequest [IP: 001e] ####

    #### Ws.Services.Transport.HTTP.WsHttpMessageProcessor::ProcessRequestMessage [IP: 0177] ####

    #### Ws.Services.Transport.HTTP.WsHttpMessageProcessor::ProcessRequest [IP: 0137] ####

    #### Ws.Services.Transport.WsThreadManager+MessageProcessor::ProcessRequest [IP: 0009] ####

    A first chance exception of type 'System.Xml.XmlException' occurred in MFWsStack.dll

    The offending section is:

    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPoxZoXC7r+opJsf1BMN+t5RAAAAAAQsSDzxG2XkGZ4g7AM7yjW4Ue1M+sdH5MprOgmAzDENcACQAA</VsDebuggerCausalityData&gt;

    To  work around this, add the following to your App Config configuration section:

    <configuration>

     <system.diagnostics>

       <switches>

          <add name="Remote.Disable" value="1" />

       </switches>

     </system.diagnostics>

    </configuration>

    And run the WCF app outside of the Vs debugger. This will be fixed in the next release of the stack.

  7. SENSEI says:

    Hello,

    i would like to gather advices on a problem i encounter : i have a DPWS host program that works perfectly on the emulator, but not at all when i deploy it on a real device (AUG elektronik one)

    To help me understand the problem, i've ran wsddebug_client.exe from the windows SDK.

    When the emulator starts, my program sends the Hello message on the multicast address and all is fine.

    But, when i deploy then run my program on the device, it sends the same Hello message to the right multicast group, but the UDP frame is split into 256 bytes chunck and so 4 frames are sent over the network and never my client understand the splitted Hello message...

    It's the same with all others UDP frames generated from the device : a max length of 256 bytes...

    Do you think this can come from the AUG hardware or from the micro framework or is it a configuration option ???

    thx for your help

    SENSEI

  8. Roel Alblas says:

    Hi,

    WCF 4.0 is in Release Candidate state now. Are there or will there be some guidelines to communicate as a DPWS device with a WCF 4.0 service with WS_Discovery?

    Thanks!

    Roel

  9. Marc says:

    Hello,

    I started working with .NET Micro Framework and I encouer an interesting problem.

    I have written a simple DPWS host and client program, when I running them booth on a emulator, the first time, anything is fine. But when I restart the client, I only get the message, that the device cannot be found.

    Is this problem only occuring by using an emulator?

    I hope you can help me with that.

    Thanks.

    Marc

  10. laporta333 says:

    i would like to have the source code of creating a device and adding services. Please

  11. Colin Miller says:

    laporta333 - is this what you are looking for?  msdn.microsoft.com/.../ff551782.aspx

  12. laporta333 says:

    thx for answering me. But in fact my problem is how to create a device with c# because i tried to implement this code msdn.microsoft.com/.../dd170121.aspx but it doesn't work , so please can u help me ??????

Skip to main content