NAVmoble - the pocket-sized ERP
Optimized for Microsoft Dynamics NAV and Windows Mobile powered devices
Showing posts with label .NET CF. Show all posts
Showing posts with label .NET CF. Show all posts

Wednesday, October 03, 2007

Mobile & Embedded Developer Chat,October 24

Neil will host another Mobile & Embedded Developer Skype Chat on 24.Oct.2007 at 3PM GMT.
Click here to add Outlook Reminder(via Neil's post)
You may ask the experts your mobile&embedded dev questions.

The chat may be accessed from the following url:
http://chat.opennetcf.com
Note that you may say hi at any time in the chat room.

The original announcement may be found here on the Neil's blog

I just noticed that Neil got his MVP status back. Contragts Neil! You deserved it!

Monday, August 06, 2007

"How To" Series: Configuring Network Adapters with Compact Framework


There was a question in the forums, if there is a way to configure a network adapter automatically - without an user interaction. Using the UI, the user may select "My network card connects to" value for every adapter in the adapters list. It may be changed to point one of the available network destinations like "The Internet" , "Work", etc. So, is there a way to this automatically?

In short the answer is YES! There is a way. We may prepare an OMA Client Provisioning File and pass it to the appropriate configuration provider in Windows Mobile.
An appropriate configuration file would be like this:


<wap-provisioningdoc>
<characteristic type="CM_NetEntries">
<characteristic type="Adapter Name">
<parm name="DestId" value="{A1182988-0D73-439e-87AD-2A5B369F808B}"/>
<parm name="Adapter" value="Qualified Name"/>
</characteristic>
</characteristic>
</wap-provisioningdoc>




This file will bind a network adapter named "Adapter Name"
to the "Work" destination. We have to change the "Adapter Name" value with
the name of the adapter as it is seen in the adapters list. The "Qualified Name" should be changed with the fully qualified name of the adapter - it may be obtained by using the GetAdaptersAddresses routine

If we want to change the destination to "The Internet" , we have to supply different GUID for the DestId parameter. Following network identifiers as configured by default on Windows Mobile:

The Internet: {436EF144-B4FB-4863-A041-8F905A62C572}
Work: {A1182988-0D73-439e-87AD-2A5B369F808B}
WAP Network: {7022E968-5A97-4051-BC1C-C578E2FBA5D9}
Secure WAP Network:{F28D1F74-72BE-4394-A4A7-4E296219390C}
CurrentDTPTNetwork:{A1182988-0D73-439e-87AD-2A5B369F808B}

What we have to do in order to apply this configuration setting?
We have the following options:
1. Preparing the provisioning Xml file , save it as _setup.xml, and place it inside a CAB file. We may "execute" the file on the device, then. Check out this post for details about deploying provisioning files with CABs.
2. We may apply these settings through code(Compact Framework) by using the managed Microsoft.WindowsMobile.Configuration.ConfigurationManager class from Windows Mobile 5 SDK:

string configurationXml = "<wap-provisioningdoc><characteristic type=\"CM_NetEntries\">"+
"<characteristic type=\"Adapter Name\"><parm name=\"DestId\" "+
"value=\"{A1182988-0D73-439e-87AD-2A5B369F808B}\"/><parm name=\"Adapter\" value=\"Qualified Name\" /> "+
"</characteristic></characteristic></wap-provisioningdoc>";
// Load XML
XmlDocument configurationXmlDoc = new XmlDocument();
configurationXmlDoc.LoadXml(configurationXml);
// Send to Configuration Manager
ConfigurationManager.ProcessConfiguration(configurationXmlDoc, false);


Also the unmanaged version DMProcessConfigXML may be used
Check out this post for unmanaged wrapper of DMProcessConfigXML

Links
CM_NetEntries Configuration Service Provider Examples for OMA Client Provisioning
Injecting Provisioning XML into a cab using VS 2005 on the Windows Mobile Blog
DMProcessConfigXML on the Marcus Perryman's WebLog
Windows Mobile Device Management for more configuration options

Tuesday, July 24, 2007

"How To" Series: Reading Device Owner Information on Windows Mobile



I noticed recently, that some guys asked(in the forums) how to read the device owner information from .NET Compact Framework.

The Device Owner information may be obtained from the device's registry. It is stored under the following registry key: HKEY_CURRENT_USER\ControlPanel\Owner






Note that, this key may be missing on a fresh device. The key is populated after the owner sets his/her information.

The registry key HKEY_CURRENT_USER\ControlPanel\Owner has two interesting values:
"Owner" and "Owner Notes". These values holds binary data.
The "Owner" value contains the following owner information attributes: Name, Company, Phone, E-mail, Address. The "Owner Notes" value contains the Notes of the owner :)
Reading Owner notes is simple like:
RegistryKey key = Registry.CurrentUser.OpenSubKey("ControlPanel\\Owner");
byte[] data = key.GetValue("Owner Notes") as byte[];
string notes = UnicodeEncoding.Unicode.GetString(data, 0, data.Length).TrimEnd('\0');

The tricky part is to "decode" the "Owner" binary data, which contains multiple fixed-length values. In order to deal with it , we have to know the exact length of every device owner attribute:

  • Name: 72 bytes
  • Company: 72 bytes
  • Address: 372 bytes
  • Phone: 48 bytes
  • Email: 74 bytes

So, reading the "Owner" info is easy as:
RegistryKey key = Registry.CurrentUser.OpenSubKey("ControlPanel\\Owner");
byte[] data = key.GetValue("Owner") as byte[];
string name = UnicodeEncoding.Unicode.GetString(data,0,72).TrimEnd('\0');
string company = UnicodeEncoding.Unicode.GetString(data,72,72).TrimEnd('\0');
string address = UnicodeEncoding.Unicode.GetString(data, 144, 372).TrimEnd('\0');
string phone = UnicodeEncoding.Unicode.GetString(data, 516, 48).TrimEnd('\0');
string email = UnicodeEncoding.Unicode.GetString(data, 566, 74).TrimEnd('\0');

You may obtain the full source code from here

Tuesday, July 10, 2007

"How To" Series: Retrieving IMSI and IMEI on Windows Mobile

I had to retrieve the IMSI and IMEI on Windows Mobile for a particular project.
What I needed actually was the IMSI , because it may be used in OMA Client Provisoning through WAP Push scenarios. It may be very practical for the enterprise to manage its devices remotely and I will post more on that topic later on.

In order to retreive IMSI and IMEI, one have to deal with the Telephony API and PInvoke. In general the magic is done by invoking the native lineGetGeneralInfo routine from TAPI.
You may download the full source code from here

the original code article may be found here

There is another approach as well - buy the Telephony library from OpenNETCF

Links
What is IMSI
What is IMEI
OMA Client Provisoning for Windows Mobile
The sample source code

Tuesday, June 26, 2007

Configuring Symbol MK1100 Micro-Kiosk


I had a project involving the development of a custom CF.NET application. The app was intended to be deployed on a number of Widnows CE 4.1 based devices from Symbol(MK1100). This device is a rather old model, however the customer had already the device on hold. These devices are custom - the vendor(Symbol in this case) decides what is this device like.
The file system in MK1100 uses a volatile memory. The device have no battery. It is plugged directly into the power supply circuit. This means that if someone unplug the device, all the executables, data and even the .NET CF will be lost and they should be deployed again. Fortunately, the device provides tools to automate the initial application deployment on boot. However, I spent a lot of time till getting the right path. I tried to find some best practices, articles or even forums discussions about the best way to deploy my app on device boot. Unfortunately I haven't found a complete guide.
It turns out that the device has a non-volatile memory that may be used to store files to live the cold boot. My first approach was to store and use the CAB, executables and data files from the non-volatile area. And that was a terrible approach, as it turned out later. The software and device behavior as a whole was unpredictable and unstable.
So my final approach was :
1. Placing all setup files(CF.NET including) into the non-volatile area.
It appears as a folder named \Application

2. Placing a file with .CPY extension in the non-volatile area. the file contains instructions for copying all the CAB files from the non-volatile area into the volatile area - e.g.\Program Files\MyApp. The .CPY files are read and executed on boot. The idea was to avoid execution of CABs from the non-volatile area.

3. Placing a .reg file in the non-volatile area.
This registry file contains device configuration information and it is read from the device on boot. The interesting part was to instruct the device that instead of launching the OS Shell, it had to launch the wceload.exe couple of times to install the .NET CF and other apps. At the it launches my custom app in kiosk mode.. Then it launches my app instead of the shell.The outcome was to have the device operating in kiosk mode...and the kiosk mode was easier on this device

On boot, the .CPY file forces the device to copy all the CABS from the non-volatile area into the volatile area. Then the .reg file forces the device to launch wceload to install all the CAB files from the non-volatile area. At the end the install the custom app is launched.

Related comments and advices are welcome!

Links
MK1100 Micro-Kiosk from Symbol
Kiosk mode in windows mobile
Window CE vs Windows Mobile

Tuesday, May 15, 2007

Kiosk mode in Windows Mobile

I had a number of questions after my talks during the MS Days 2007 in Sofia.
And there was a question that I failed to give a complete and detailed answer.So here comes the answer...
Before taking this path, take a break and think if the kiosk mode is actually needed for your app. Windows Mobile is designed as a general purpose OS, intended for personal usage. The kiosk mode app will prevent the users from using it as their personal device. You may want to check the Marcus Perryman's post for arguments about Kiosk Mode vs Deep Integration choices
Anyway, there are several options to have the app in kiosk mode over Windows Mobile:
1.Replacing the standard password prompt
One should create a DLL, export the PromptForPasswd function and than hacking the registry to use your custom password prompt. There are some side-effects and also this method may fail on some devices. So test it with a real hardware.
Check out this resource for details

2. Maximizing your application's main form
In general maximizing the app's main form will get you a kiosk-alike behaviour. However, the user may press the hardware buttons to get to another app. Some OS events (like inbound phone call)may pop up another app in front of yours . In other words this solution will not give you a complete kiosk mode.
Check out the newsgroups:
SHFullScreen
Full Screen on CF.NET

3.Replacing the standard shell
Check out this post for additional info about shells

4. Hiding the Windows Mobile task bar
This is not a complete solution, but a complementary technique.
Check out the following link for an example

5. Using third-party framework.
Check out the following ones:
Spb Kiosk Engine
PocketKiosk Builder


Links
Spb Kiosk Engine
PocketKiosk Builder
Hiding the taskbar
Prompt For password
Marcus Perryman on Kisok mode in Windows Mobile
Windows Embedded Blog on kiosk mode in Windows CE
Newsgroups on Fullscreen with SHFullScreen
Newsgroups on Full Screen/CF.NET
Kiosk mode on Pocket PC
Kiosk Pattern from Satter Ramblings
WM Shell replacement

Update
Check out this post for more resources as well

Tuesday, April 10, 2007

SqLite: Improve database experience with managed user-defined functions

Are you using SQLite?

SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.


A good .NET and Compact Framework Providers may be obtained from here

It is very fast! However the speed comes to a price - no foreign keys, no stored procedures, etc.

One of the major challenges with SqLite for me was related to a problem with the ciryllic supopport. In general, if one tries to execute an sql query containing the expression "upper(MyField) = @MyField " may get unexpected result. The SqLite UPPER function has a problem, when dealing with Cyrillic characters.
So is there a solution?
I came with 2 solutions(Both have issues):
1. Store only upper characters in the database and do not use the UPPER function
2. Implement custom managed "Upper" function for SQL:

[SQLiteFunction(Name="CYR_UPPER",Arguments=1,FuncTyp=FunctionType.Scalar)]
public class SqLiteCyrHelper:SQLiteFunction
{
public override object Invoke(object[] args)
{
return args[0]!=null?((string)args[0]).ToUpper():null;
}
}


Then you may use it in the following way:

SELECT * FROM my_cyr_table WHERE cyr_upper(cyr_column) = @cyr_string

This all comes with a performance cost, however it is a very powerful way to enhance the database experience.

SQLite supports custom aggregates , collate and scalar function and the sqlite.phxsoftware.com implementation allows these function to be written in managed code.

UPDATE:

Do not forget to register the function on application startup:
SqLiteCyrHelper.RegisterFunction(typeof(SqLiteCyrHelper));


Links:

Managed SQLite Provider (.NET & compact Framework)

SQLite.org - the offical SQLite web site



Enjoy!

Sunday, February 04, 2007

“How to” Series: Windows Mobile Security Configurations

I've plugged a new Windows Mobile 5 device to my dev box and tried to deploy and debug a simple Compact Framework app. The device was HTC P3600 and it was obtained from a local mobile operator. However, the VS2005 complained that it can't deploy the app, because the device's security configuration does not permit debugging

The message said: "Unable to start program…"

I just wanted to debug, but no luck!
In order to deal with such issues, one should check out the following resource:
Windows Mobile 5.0 Application Security

Assuming, you are familiar with the concepts discussed in the resource given, I will outline some of the possible options: First we need the right tools to work with the security configurations. There are some "low-level" tools , but I personally find the Security Configuration Manager Powertoy for Windows Mobile to be a very useful toy.


Cradle the device and start the Security Conf. Manager
The right part of the screen displays the current device security configuration.
See the underlined labels? I'll explain the most important ones:

  • Configuration type shows the name of the standard security configuration loaded.
  • Security model
    shows if the device support trusted or normal execution mode. Only the Smartphone platform supports two tier security model. The PocketPC devices are one tier. It means that apps always run in trusted mode on PocketPC based devices.
  • Prompt indicates if the user is prompted, when unsigned app is about to be launched.
  • Unsigned applications- shows if unsigned application may be launched.

You may try the following scenarios in order to proceed with the day-to-day development normally:

  1. Scenario 1: Do not sign your app
    If Unsigned applications are allowed for execution you may debug and deploy without signing your app. However depending on the security configuration you app may run in normal mode (no access to specific APIs and resources). If the Prompt option is on, the device will show a confirmation message box every time your app is about to be launched. And that could be very annoying.
  2. Scenario 2: Sign your app

    This is the recommended scenario if Unsigned applications are not allowed for execution.

    1. Try to install a development certificate on the device.
      Go to the Security Configuration Manager and click "Add Development Certificate" from the "Device" menu. If the operation fails, you should consider contacting the deice vendor for a development certificate. Checkout the configuration type. Is it Locked or Third-Party Signed?
    2. Sign your app with a development certificate
      Although you may sign your app with the Security Configuration Manager, it is not practical enough during the development phase. Use the Visual Studio 2005 for that purpose. Use the Devices tab from the Project Properties (right click from the Solution Explorer). See the Signing an Application During Day-to-Day Development topic from the Windows Mobile 5.0 Application Security article for details.

    3. Deploy and debug your signed app.

  3. Scenario 2: Turn-off security
    This scenario is not recommended, because it is unlikely to have a commercial device with Security-Off. The development environment will be too different from the production one and may produce unexpected behavior. At least consider testing your app before releasing in a security configuration close to the production one.

    1. Provision device with the Security-Off Security configuration

      Select "Security-Off" from the dropdown list under "Selected Configuration" and click the "Provision" button. Wait until the device is provisioned with the new configuration.

    2. Deploy and Debug without signing your apps



Links:
Windows Mobile 5.0 Application Security
Windows Mobile 5.0 Security Model FAQ
Codesigning for Windows Mobile-based Smartphones and Pocket PCs
Security, Deployment, and Management

Saturday, December 09, 2006

"How To" Series: Building a Signature Control in Compact Framework

It is not a rare requirement for a mobile application to provide functionality for capturing a person signature.
So, let's see if we can provide this feature into a mobile application with .NET Compact Framework.
The image bellow outlines the problem that we want to solve:



We have a mobile salesman, who collects customer orders. Our salesman should collect the customer's signatures along with the order's details. Our salesman is carrying a Pocket PC device. We should create
a software solution to allow customer's signature capturing and transmition of the signature over the wire to the office. There we have a Sql Server database to store the signatures into and signatures consuming app. , which may process the stored signatures.


We should solve the following tasks:



  1. Capturing a signature from a person from the mobile device
  2. Saving the captured signature locally on the mobile device
  3. Transmitting the saved signature over the wire and storing it on the server side
  4. Consuming the transmitted and saved signature on the server side

Let's try to solve these tasks:


Solving Task 1: Capturing a signature from a person on the mobile device


If a person should place its signature on a Pocket PC, he will probably use the stylus to write his signature on the Pocket PC screen. All we have to do is to capture the on-screen tapings and convert them into a bitmap. We will create a User Control to encapsulate this functionality. The main functionality is divided between the following UserControl event handlers:



  • OnMouseDown - here we will "remember" the coordinates of the last on-screen tapping
  • OnMouseMove - here we will draw a line from the remembered coordinates to the new(after the mouse move) on-screen mouse coordinates.


Following code example(simplified version)
...
private Bitmap SignatureImage;
private Graphics GraphicsHandle;
privte Point MouseCoords;
....
SignatureImage = new Bitmap(this.Width, this.Height);
GraphicsHandle = Graphics.FromImage(SignatureImage);
...
//remembering the coords of the last on-screen tapping into  MouseCoords member
protected override void OnMouseDown(MouseEventArgs e)
{
  base.OnMouseDown(e);
  MouseCoords.X = e.X;
  MouseCoords.Y = e.Y;
}
//draw a line from the remembered coords to the new on-screen tapping coords
protected override void OnMouseMove(MouseEventArgs e)
{
  base.OnMouseMove(e); 
  GraphicsHandle.DrawLine(SignaturePen, MouseCoords.X, MouseCoords.Y, e.X, e.Y); 
  MouseCoords.X = e.X;
  MouseCoords.Y = e.Y;

//saves the captured bitmap image into a stream
public void Save(Stream stream)
{
   SignatureImage.Save(stream, ImageFormat.Bmp);
}  


Solving Task 2: Saving the captured signature locally on the mobile device


This task is simpler. Let's pretend, we should save the captured image into a local SqlServer Mobile database.
We should have a table containing a field of type image to save the signature into it.



CRATE TABLE CUSTOMERSIGN
{


   customerNo:int not null identity
   sign:image
}


Following the code to save the captured signature:


//our signature control placed into a form
private
SignatureControl MySignatureControl;
...
string connectionString =  ...;
...
using (SqlCeConnection connection = new SqlCeConnection(connectionString))
{
  connection.Open();
  SqlCeCommand command = new SqlCeCommand("INSERT INTO CUSTOMERSIGN(sign)VALUES(?)", connection); 
 


  //getting the captured signature as stream
  MemoryStream signStream = new MemoryStream();
  MySignatureControl.Save(signStream);


  param = new SqlCeParameter("sign", SqlDbType.Binary);
  param.Value = signStream.ToArray();
  command.Parameters.Add(param);


  command.ExecuteNonQuery();
  connection.Close();
}
Now we have the signature saved locally...
We may save the signature into another storage type like a file for example.


Solving Task 3: Transmitting the saved signature over the wire


Usually the most valuable mobile applications provide functionality to send and receive data to/from some in-house systems running in the company's office.
Let's see if we can send the captured image back to the office over the wire. Although there are various communication options that may be used to transmit the signature over the wire, we will see only the Xml Web Services way in this article. Other possible options are TCP/IP transmition with sockets, Merge Replication,RDA  and why not E-mail .
First, we should create our Xml Web Service. This Xml Web Service will run on the company's office web server. The web server its self should be "http reachable" by  our PocketPC. So, when our Pocket PC device gets a network connection, it may invoke our Xml Web Service and send all the captured signs back to the office.
Let's have a similar table (CUSTOMERSIGN) created into a Sql Server, which also runs in our office. Our Xml Web Service will receive the captured signatures from the mobile app. and will save them into the CUSTOMERSIGN table in the Sql Server. Later another app. may fetch the stored signs to process them in some way.


The  Xml Web Service will have one web method like this:




[WebMethod]
public void TransmitSignature(int customerId, byte[]
signature)
{
  using(SqlConnection connection = new SqlConnection(connectionString))
  {
     SqlCommand insertCmd = new SqlCommand("INSERT INTO CUSTOMERSIGN(customerId,sign)VALUES(@customerId,@signature)", connection); 
     insertCmd.Parameters.AddWithValue("@customerId", customerId); 
     insertCmd.Parameters.AddWithValue("@signature",signature);
     insertCmd.ExecuteNonQuery();
  }


}


Then on the mobile side, we may create a web reference to our Web service and consume it, when a network connection is available


OfficeService.SignService signService = new OfficeService.SignService();
using(SqlCeConnection cnn = new SqlCeConnection(connectionString))
{      


        SqlCeCommand cmd = new SqlCeCommand("SELECT customerId,signature FROM CUSTOMERSIGN",cnn);
        SqlCeDataReader reader  =  cmd.ExecuteReader();
        while(reader.Read())
        {
            int customerId= (int)reader[0];


            //read the signature from the mobile database
            int imgSize = reader.GetBytes(1,0,null,0,0); 
            byte[] signImageData = new byte[imgSize];
            reader.GetBytes(1,0,signImageData,0,0); 


            //transmit signature over the wire
            signService.TransmitSignature(customerId,signImageData);
         }          


         //delete transmited signatures from the mobile database
         
SqCeCommand deleteCmd = new SqCeCommand("DELETE FROM CUSTOMERSIGN",cnn);
         deleteCmd.ExecuteNonQuery();
 } 


Note, that this example is not quite efficient from a performance point of view. It will be more performant to have a Web Method, which accepts
a collection of signatures at a time. It may be performed easily by using DataSet to fetch and  transfer the captured signatures:

[WebMethod]
public void
TransmitSignature(DataSet signatures
)

Solving Task 4: Visualizing the transmited signature on the server side


Once we have the captured signatures saved on the server side, we may need to consume them. For example we may want to show them as images on the screen.
In order to do this we should fetch them from the database:



//picturebox control to show the signature
private PictureBox pictureBox1;
...
int interestingCusotmerId;
 ...
SqlCommand cmd = new SqlCommand("SELECT signature FROM CUSTOMERSIGN WHERE customerId=@customerId", connection);
cmd.Parameters.AddWithValue("@customerId",interestingCusotmerId);
SqlDataReader reader  =  cmd.ExecuteReader();
if(reader.Read())
{
    //read the signature from the database
    int imgSize = reader.GetBytes(0,0,null,0,0); 
    byte[] signImageData = new byte[imgSize];
    reader.GetBytes(0,0,signImageData,0,0);
    //show the signature as Bitmap image
    using(MemoryStream ms = new MemoryStream(signImageData))
    {
      pictureBox1.Image = new Bitmap(ms);
    }
}          


The presented example is not a complete solution. It just outlines some of the common problems, which should be addressed if one needs to build a signature capturing solution. 
A real world solution may be far more complicated and should address a lot of problems not mentioned here. For example there are other signature capturing techniques ,which may store the signature in more compressed format. One may need to encrypt/decrypt the captured signature to protect it or validate the signature(biometric). Please see the links bellow for more examples.



Links:


Friday, December 01, 2006

"How To" Series: Detect network connection in Compact Framework

There is several ways to accomplish this and I will outline some of them in this post.


The following snippet may be used to detect if the device is connected to a network.
It checks if the device has an IP address assigned. This approach will not work properly if the device has a static IP. It is not guaranteed that a specific network destination is reachable.


bool IsConnected
{
    get
    { 
        try
        {  
            string hostName = Dns.GetHostName(); 
            IPHostEntry curHost = Dns.GetHostByName(hostName); 
            return curHost.AddressList[0].ToString() != IPAddress.Loopback.ToString(); 
        } 
        catch
        {
            return false; 
        }
    }
}


Another possible approach is to check if there is a "path" to a specific destination.


public bool IsNetworkPathAvailable(string destinationAddress)
{
     bool connected = false
     HttpWebRequest request;
     HttpWebResponse response;
     try
     {
          request = (HttpWebRequest)WebRequest.Create(destinationAddress);
          response = (HttpWebResponse)request.GetResponse();
          request.Abort(); 
          if (response.StatusCode == HttpStatusCode.OK)
         {
              connected = true;
         }
    }
    catch (WebException ex)
    {
        connected = false;
    }
    catch (Exception ex)
    {
       connected = false;
    }
    finally
    {
       if(response != null)
          response.Close();    
    }
    return connected;
 }
//here we will use the network detection
if(IsNetworkPathAvailable(http://www.ritsoftware.com"))
            SendSomeDataOverTheWire();  


Another way to accomplish this is to use the InternetGetConnectedState function from wininet.dll
[DllImport("wininet.dll")]
private static extern bool InternetGetConnectedState(ref uint flags, uint dwReserved);

public bool IsConnected
{
   get
   {
        uint flags;
        return InternetGetConnectedState(ref flags,0);
   }
}  


 


Links
ConnectionManager class from www.opennetcf.org
Compact Framework Newsgroups


 


 


 

Wednesday, November 01, 2006

WCF on the mobile side

Roman Batoukov has a post explaining in details the plans about providing Windows Communication Foundation support in the .NET Compact Framework.
The programming model provided will be limited to channel layer messaging only. It will be extensible, so the developers eventually will be able to implement their own transports. Few out-of-the box transport channels will be delivered like Http and E-mail.

Roman discusses some common problems regarding the devices communication , their solutions(when the WCF is out) and the feature of the E-mail as a messaging transport.

Read the full article