Welcome to MSDN Blogs Sign in | Join | Help
How to use the WS-Discovery Library that ships with BizTalk RFID 2009

BizTalk RFID 2009 ships a Discovery library that provides an easy interface to leverage WS-Discovery to discover WS-Discovery enabled devices. WS-Discovery support was first included with the BizTalk RFID Standards Pack and comes out of the box with BizTalk RFID 2009.

 

The Discovery library is intended for the use of provider writers to help them easily discover devices that support WS-Discovery. The WS-Discovery protocol uses SOAP and UDP multicast to enable services to be discovered by a client. In the BizTalk RFID world, services discovered are RFID devices and the client is a BizTalk RFID provider.

 

Here’s a quick view of the messages that the Discovery library supports sending (or receiving) and their function in the WS-Discovery protocol:

-          Hello - A service (the device) sends a Hello message by using UDP multicast when it joins a network

-          Bye - A service sends a Bye message when it prepares to leave the network

-          Probes - A client (the BizTalk RFID provider) sends a Probe message by using UDP multicast looking for services it is interested in. Matching services respond with ProbeMatch messages

 

A provider writer chiefly needs to work with the class WSDiscoveryForDspi in namespace Microsoft.Rfid.Discovery. Here’s a wrap of the methods in this class, their functionality, and where they fit in the provider:

-          StartDiscovery

o   This method causes the discovery library to start listening for Hello and Bye messages on the network.

o   This should be called from within the DeviceProvider.StartDiscovery() method.

o   To respond to Hello and Bye messages, the provider should subscribe to the events OnDeviceAdded and OnDeviceRemoved exposed by the WSDiscoveryForDspi class. OnDeviceAdded is raised when a Hello is received and OnDeviceRemoved is raised when a Bye is received.

o   The StartDiscovery method can be passed a MatchCriteria argument to limit the range of devices that are searched. See here for details.

 

        public override void StartDiscovery()

        {

    m_discoveryForDspi.StartDiscovery(m_matchCriteriaRfidDeviceType);

        }

 

-          StopDiscovery

o   This stops the listening for Hello and Bye messages

o   Should be called from within the DeviceProvider.StartDiscovery() method.

 

-          SearchAsync

o   This causes the Discovery library to send a Probe and wait for ProbeMatch messages

o   The time duration of the wait for ProbeMatch is defined by MatchTimeout property of the WSDiscoveryForDspi class. After the time is up the SearchCompleted event is raised

o   On receiving a ProbeMatch, the OnDeviceAdded event is raised

o   This can also be passed MatchCriteria like the StartDiscovery method.

o   This should be called from within the TriggerDiscovery method



Handling the OnDeviceAdded event – If an OnDeviceAdded event is received (i.e. either a Hello or a ProbeMatch was received from a device), the provider has found a device successfully. That means it should raise a DiscoveryEvent to the BizTalk RFID service. The OnDeviceAdded event passes a WSDiscoveryEventArgs argument to the event handler method. This has a number of useful properties that give the XAddrs element, Types element etc in the Hello or ProbeMatch message from the device. This argument needs to be converted to the type DiscoveryEventArgs understood by the BizTalk RFID service. The Discovery library provides a utility method for this -  ConvertToDspiDiscoveryEventArgs - the use of which is shown below.

 

        void discoveryForDSPI_OnDeviceAdded(object sender, WSDiscoveryEventArgs e)

        {

            if (DiscoveryEvent != null)

            {

                DiscoveryEventArgs args = discoveryForDSPI.ConvertToDspiDiscoveryEventArgs(e);

                DiscoveryEvent(this, args);

            }

        }

 

A WS-Discovery sample provider is included in the BizTalk RFID 2009 samples and can be used as a base for developing WS-Discovery providers.

 

References:

Standards support in BizTalk RFID 2009 http://blogs.msdn.com/krishg/archive/2009/03/26/biztalk-rfid-and-standards-support.aspx

DiscoveryLibrary documentation http://msdn.microsoft.com/en-us/library/dd298783.aspx

DeviceConnectionDownEvent and how it is expected to be used by device providers

When a device provider should raise the DeviceConnectionDownEvent is a topic of some confusion. The Contoso device provider sample gave a wrong example of its use till recently. The sample has the following code inside the PhysicalDeviceProxy.Close method:

 

DeviceConnectionDownEvent mgmtEvent = new DeviceConnectionDownEvent("Closing connection for device " + this.DeviceInformation.DeviceId);

Notification notification = new Notification((DeviceManagementEvent)mgmtEvent);

this.raiseNotificationEvent(new NotificationEventArgs(notification));

 

While there is nothing wrong with this code in itself, the place where it is being executed is wrong. The PhysicalDeviceProxy(PDP)'s Close method is called by the RFID platform when the user closes a device connection. Also, the consumer of the raised DeviceConnectionDownEvent event is also the RFID platform. So this is what happens: a user closes a device connection -> the RFID platform calls PDP.Close() -> PDP.Close() raises the DeviceConnectionDownEvent -> the RFID platform receives this event and thinks that the provider has detected that a device cannot be cannot be contacted any more and takes some action accordingly.

The RFID platform expects the DeviceConnectionDownEvent to inform it of a device connection going down. Raising the event when the platform itself has closed the device connection defeats the purpose. So the above code, while valid, should be taken out of the PDP.Close method. It should be called by the provider if it proactively detects that a device cannot be contacted.

What is the purpose of the Deploy and Init methods of an event handler?

You might have observed that every time you start a process from RFID Manager, both the methods Deploy and Init of every event handler (EH) in the process are called. This raises the question: why have these two separate methods at all?

The answer lies in user account permissions. While calling the Deploy method of an EH, the RfidService impersonates the caller's identity. All other methods of an EH (including Init) are executed with the identity of RfidWorkerProcessAcc. If an EH wants to do some setup kind of work that requires higher priviledges (such as creating a database) that are not available to RfidWorkerProcessAcc, it is expected to put this work inside the Deploy method.

Of course, stuff like creating a new database is a one time thing and shouldn't need to be done every time a process is started. In fact RfidClientConsole.exe's startprocess command does not call Deploy at all, only doing an Init for starting the process. RFID Manager has taken the safe option of calling the Deploy every time. An EH is expected to be tolerant of being deployed multiple times.

What is the meaning of provider status "Started-Unhealthy"

This generally happens if the provider throws an unhandled exception.

The RfidTools logs are unlikely to help much in fixing this. The exception is logged in the RfidServices logs as a warning. But the best place to look for the bug are the provider logs (%rfidinstalldir%\Providers\<provider name>\*.Log).

Calling business rules from an RFID process

Given how easy it is to call BRE rules from a Microsoft BizTalk RFID process, it's surprising how few people make use of this feature. And that gives me a topic to blog about!

So, here starts my first post...

BizTalk RFID provides support for executing BRE policies through two classes that are inside microsoft.rfid.oobcomponents.dll: RuleEnginePolicyExecutor and RfidRuleEngineContext.

RuleEnginePolicyExecutor, like SqlServerSink, is an out-of-the-box component that can be added to an RFID process. It is available in New Process->Bind wizard-> New Component. Adding the component opens a prompt asking for the BRE policy to be executed. XML facts and database facts to be asserted to this policy can also be specified here.

RuleEnginePolicyExecutor is responsible for executing the specified BRE policy. It puts together the XML and database facts specified while adding the component with .net objects passed by previous event handlers (RfidEventContext.Data) along with an instance of RfidRuleEngineContext to make a complete list of facts to be passed to the BRE policy.

RfidRuleEngineContext is passed as a fact to the BRE policy and contains several useful functions like GetTagID, GetTagData, UpdateVendorSpecificData, GetSource that can be used to make BRE rules. In the Business Rules Composer, this class can be used as a .NET fact by browsing the gac to select microsoft.rfid.oobcomponents.dll. From here on, we can drag and drop functions from this class to make rules in the cool Business Rules Composer way.

Page view tracker