Broadcasting technical support to Windows Mobile\CE Application Developers to help realizing their potential

Establishing GPRS Connection on Windows CE and Windows Mobile: Sample Codes

Establishing GPRS Connection on Windows CE and Windows Mobile: Sample Codes

  • Comments 22

Sometimes developers asking for support have straightforward goals they want to achieve with the minimal amount of code, even if the "application" will work only on very specific scenarios. This was the case for a request I handled, where the goal was: connect the device via GPRS to Internet, when it's not cradled to a desktop PC and WiFi is not available. As you may know connections in Windows Mobile are entirely handled by the Connection Manager, and developers are "encouraged" on using only Connection Manager APIs, as long as you want CM-aware applications to run as expected. For example, IE Mobile is a CM-aware application: if you open a GPRS connection through RAS APIs as documented in the Windows *CE* documentation (see here), then Connection Manager wouldn't sense it and IE Mobile would request a new one. A well done article about this for mobile developers was written by Jim Wilson and is available here.

So, the "recommended" way on Windows Mobile is to invoke CM APIs, while on Windows CE you can use for example RAS APIs (CM is not available) - see below. Note that this code is meant to work when no other less expensive networks are available (ActiveSync\WMDC's Desktop-Passthrough, WiFi).

#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include "connmgr.h"



GUID GetNetworkForURL (LPCTSTR url)
{
    DWORD dwIndex = 0;
    GUID rv;
    if (!SUCCEEDED (ConnMgrMapURL (url, &rv, &dwIndex)))
        rv = GUID_NULL;

    return rv;
}


HRESULT EstablishConnection (LPCTSTR url, DWORD retries, DWORD timeout, DWORD* dwStatus, HANDLE hConnection)
{
    CONNMGR_CONNECTIONINFO ConnectionInfo;
    ZeroMemory (&ConnectionInfo, sizeof (ConnectionInfo));
    ConnectionInfo.cbSize = sizeof (ConnectionInfo);

    ConnectionInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET; 
    ConnectionInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP; 
    ConnectionInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE; 
    ConnectionInfo.guidDestNet = GetNetworkForURL (url);

    return ConnMgrEstablishConnectionSync (&ConnectionInfo, &hConnection, timeout, dwStatus);
}


    //
    // Called when there was an error while connecting
    // generally due to network connection not being available (no modem, no nic etc).
    //
    HRESULT DoConnectingError(DWORD dwStatus)
    {
        // we received an error to do with connecting.
        SHELLEXECUTEINFO sei = {0};
        TCHAR szExec[MAX_PATH];
        wsprintf( szExec, TEXT("-CMERROR 0x%x -report"), dwStatus );
        sei.cbSize = sizeof(sei);
        sei.hwnd = NULL;
        sei.lpFile = TEXT(":MSREMNET");
        sei.lpParameters = szExec;
        sei.nShow = SW_SHOWNORMAL;
        ShellExecuteEx( &sei );
        return E_FAIL;
    }


int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwStatus = 0;
    HANDLE hConnection = NULL;

    LPCTSTR url = L"http://www.msn.com"; //just to set Internet network - and no need for proxies
    HRESULT hr = EstablishConnection (url, 10, 25000, &dwStatus, hConnection);

    if ( FAILED( hr ) )
    {
        DoConnectingError(dwStatus);
    }

    ConnMgrReleaseConnection(hConnection, TRUE);
    return 0;
}

 

while on Windows CE-based devices:

//TODO: ADD ERROR-CHECKING
BOOL ConnectGPRSonWindowsCE()
{
    HRASCONN hRASConnection = NULL;
    DWORD nRet;

    RASENTRYNAME TempEntryName;
    TempEntryName.dwSize = sizeof(RASENTRYNAME);
    unsigned long EntryBufferSize = sizeof(TempEntryName);
    unsigned long EntryWritten = 0;

    //ERROR_BUFFER_TOO_SMALL is expected
    nRet = RasEnumEntries( NULL, NULL, &TempEntryName, &EntryBufferSize, &EntryWritten );
    if (nRet != ERROR_BUFFER_TOO_SMALL)
    {
        WCHAR strErr[255];
        wsprintf(strErr,L"RasEnumEntries failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;
    }

    RASENTRYNAME *RasEntryNameArray = (RASENTRYNAME*)malloc(EntryBufferSize);
    RasEntryNameArray[0].dwSize = sizeof(RASENTRYNAME);
    nRet = RasEnumEntries( NULL, NULL, RasEntryNameArray, &EntryBufferSize, &EntryWritten );
    if (0 != nRet)
    {
        WCHAR strErr[255];
        wsprintf(strErr,L"RasEnumEntries failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;
    }

    int GPRSEntry = -1;

    RASENTRY RasEntry;
    memset( &RasEntry, 0, sizeof(RasEntry) );
    RasEntry.dwSize = sizeof(RasEntry);
    DWORD dwEntrySize = sizeof(RasEntry);
    unsigned char Buffer[4098];
    memset( Buffer, 0, sizeof(Buffer) );
    DWORD dwBufferSize = sizeof(Buffer);

    for ( unsigned long iEntry = 0; iEntry < EntryWritten; iEntry++ )
    {
        // Check if the name has GPRS in it 
        // AND
        // if Local Phone Number contains "~GPRS!"
        nRet = RasGetEntryProperties(NULL, RasEntryNameArray[iEntry].szEntryName, &RasEntry,&dwEntrySize,NULL,NULL);
        if (0 != nRet)
        {
            WCHAR strErr[255];
            wsprintf(strErr,L"RasGetEntryProperties failed: Error %d\n", nRet);
            MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
            return FALSE;
        }

        if ((wcsstr(RasEntry.szLocalPhoneNumber,L"~GPRS!") != NULL) 
            &&
            (wcsstr(RasEntryNameArray[iEntry].szEntryName, L"GPRS") != NULL))
        {    
            //RAS entry is GPRS - exit 'for' loop
            GPRSEntry = iEntry;
            break;
        }
    }

    nRet = RasGetEntryProperties( NULL, RasEntryNameArray[GPRSEntry].szEntryName, &RasEntry, &dwEntrySize, Buffer, &dwBufferSize );
    if(0 != nRet)
    {
        WCHAR strErr[255];
        wsprintf(strErr,L"RasGetEntryProperties failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;
    }

    // Configure the RASDIALPARAMS structure
    RASDIALPARAMS RASDialParameters;
    memset( &RASDialParameters,0,sizeof( RASDIALPARAMS ) );
    RASDialParameters.szPhoneNumber[0] = NULL; //TEXT('\0');
    RASDialParameters.szCallbackNumber[0] = NULL; //TEXT('\0');
    RASDialParameters.dwSize = sizeof( RASDIALPARAMS );
    wcscpy( RASDialParameters.szEntryName, RasEntryNameArray[GPRSEntry].szEntryName);
    RASDialParameters.szUserName[0] = TEXT('\0');
    RASDialParameters.szPassword[0] = TEXT('\0');
    RASDialParameters.szDomain[0] = TEXT('\0');
    //wcscpy (RasDialParams.szUserName, szUserName); //This is optional    
    //wcscpy (RasDialParams.szPassword, szPassword); //This is optional
    //wcscpy (RasDialParams.szDomain, szDomain); //This is optional


    //try reuse GPRS connection
    BOOL bPassword = FALSE;
    nRet = RasGetEntryDialParams(NULL, &RASDialParameters, &bPassword);
    if (0 != nRet)
    {
        WCHAR strErr[255];
        wsprintf(strErr,L"RasGetEntryDialParams failed: Error %d\n", nRet);
        MessageBox(NULL, (LPCTSTR)strErr, L"GPRS Monitor", MB_OK);
        return FALSE;
    }

    //free resources not on the stack
    free ((VOID*)RasEntryNameArray);
    
                
    //  Try to establish RAS connection.
    if ( RasDial( NULL, NULL, &RASDialParameters, 
            NULL, // Notifier type is NOT a window handle
            NULL, // Window receives notification message - none
            &hRASConnection ) != 0 )
    {
        if ( hRASConnection != NULL )
            RasHangUp( hRASConnection );
        hRASConnection = NULL;
        MessageBox (/*hDlgWnd*/NULL, L"Could not connect using RAS", /*szTitle*/ L"GPRS Monitor", MB_OK);
        return FALSE;
    }

    hRASConnection = NULL;
    return TRUE;

}
 
Leave a Comment
  • Please add 2 and 6 and type the answer here:
  • Post
  • This post is somehow related to a previous one ( Establishing GPRS Connection on Windows CE and Windows

  • I have a related problem. I do not know if this is right forum to ask. If this is not the right forum, can you please direct me to right forum please?

    I am using Windows CE 4.2, and I wanted Bluetooth USB Dongle to connect to PC using ActiveSync.  Here are the things I did:

    1.  Include Bluetooth USB driver in Platform Bilder Project

    2. Included ASUI sample application in my CE platform

    3. Updated the registry accordingly.

    4. It creates RAS entry for Bluetooth, but when it calls RasDial, it returns with error code 608, device not found.

    5. On the PC side, I have ActiveSync setting, selecting the BT virtual COM port.

    Bluetooth stack on CE device is loaded, I can see the CE device from my laptop. But it does not see any service on CE device.

    Thanks for your help.

  • Hi Santosh,

    The topic is a bit different (here I was talking about GPRS, you're interested on Bluetooth and ActiveSync). You may ask to MSDN Forums, probably the best one for you is http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=34&SiteID=1. If you won't find a solution, you may also open a request at Microsoft Technical Support.

    Thanks!

    ~raffaele

  • Hi, I have some problems in connecting the windows CE 5.0 platform to a Siemens GPRS modem (mod. TC35). I followed the instructions on this site (http://e-consystems.com/gprs.asp). I have a serial connection between the platform and the modem. I insert a Vodafone SIM card in to the modem.

    I create a new dial up connection as shown on the site: baudrate 19200 (the modem supports util 115 kB), no parity, hw flow control..  then I insert the special modem command: +cgdcont=1, "IP", "internet". My phone number is *99***1#. So I doible click on my new connection and don't insert username and pwd. When the platform tries to connect, on the screen appears the following error message: "the port is not available: another program may be using it. What should I do to let the platform and the modem work correctly? thanks.

  • Hi Forzafaith, personally I suggest to touch base with the Windows CE's OEM to see if your issue is OEM-specific: it may well be that the "another program" the error message is talking about is OEM's. HTH.

  • Hi Raffael,

    How can I set the APN for the Dial-Up?

  • Hi afriza,

    On Windows Mobile, you can use XML Provisioning and specifically the CM_GPRSEntries. On Windows CE, you should use RasSetEntryDialParams to set the RASDIALPARAMS structure you need later to retrieve through RasEnumEntries. You may start from http://msdn.microsoft.com/en-us/library/aa922037.aspx.

    HTH,

    ~raffaele

  • Hi Raffaele,

    I've taken a look at RasSetEntryDialParams() and RasSetEntryProperties() but I haven't found any APN related variables, or did I missed out something here?

    afriza

  • Maybe because the sample code at the page I mentioned (http://msdn.microsoft.com/en-us/library/aa922037.aspx) omitted such parts...

     // Insert code here to fill the RASENTRY structure.

     // ...

    ...

     // Insert code here to fill up the RASDIALPARAMS structure.

     // ...

    but this is where you can set the APN related variables. For example:

    RASENTRY RasEntry;

    RASIPADDR EmptyIP = {0,0,0,0};

    memset (&RasEntry, 0, sizeof(RASENTRY));

    RasEntry.dwSize = sizeof(RASENTRY);

    RasEntry.dwfOptions = 0;

    RasEntry.dwCountryID = 0;

    RasEntry.dwCountryCode = dwCountryCode;

    _tcscpy (RasEntry.szAreaCode, lpszAreaCode);

    _tcscpy (RasEntry.szLocalPhoneNumber, lpszPhoneNumber);

    RasEntry.dwAlternatesOffset = 0;

    RasEntry.ipaddr = EmptyIP;

    RasEntry.ipaddrDns = EmptyIP;

    RasEntry.ipaddrDnsAlt = EmptyIP;

    RasEntry.ipaddrWins = EmptyIP;

    RasEntry.ipaddrWinsAlt = EmptyIP;

    RasEntry.dwFrameSize = 1500;

    RasEntry.dwfNetProtocols = RASNP_Ip;

    RasEntry.dwFramingProtocol = RASFP_Ppp;

    _tcscpy (RasEntry.szScript, TEXT(""));

    _tcscpy (RasEntry.szAutoDialDll, TEXT(""));

    _tcscpy (RasEntry.szAutoDialFunc, TEXT(""));

    // _tcscpy (RasEntry.szDeviceType, RASDT_Modem);

    _tcscpy (RasEntry.szDeviceType, RASDT_Direct);

    _tcscpy (RasEntry.szDeviceName, lpszModemName);

    _tcscpy (RasEntry.szX25PadType, TEXT(""));

    _tcscpy (RasEntry.szX25Address, TEXT(""));

    _tcscpy (RasEntry.szX25Facilities, TEXT(""));

    _tcscpy (RasEntry.szX25UserData, TEXT(""));

    RasEntry.dwChannels = 1;

    RasEntry.dwReserved1 = 0;

    RasEntry.dwReserved2 = 0;

    RetVal = RasSetEntryProperties (

    NULL,

    lpszEntryName,

    &RasEntry,

    sizeof(RasEntry),

    NULL, //default DEVCFG parameters

    0);

  • Hi Raffaele,

    Thank you for your replies,

    maybe I misunderstood something, but what I want to set is something like "internet" value for Access Point Name ( APN, as described in the example in http://en.wikipedia.org/wiki/Access_Point_Name ).

    I think it corresponds to the GPRSInfoAccessPointName parameter in the XML Provisioning.

    However, I find no corresponding variable in RASENTRY ( http://msdn.microsoft.com/en-us/library/aa920252.aspx ) nor in RASDIALPARAMS ( http://msdn.microsoft.com/en-us/library/aa920539.aspx )

    previously I used to open a serial port and send AT command +cgdcont=1, "IP", "internet" to set the APN. I wonder if there is a better way using some APIs.

    Thank you again and regards,

    afriza

  • Just for clarification, I am developing for Windows CE.

  • You should set Extra dial-string modem commands, for example thru the registry under HKLM\ExtModems\<ModemDriver>\Init. I'm referring to a string like AT+CGDCONT=1,"IP","myAPN.com", I'm sorry I don't have a sample code right now but you may be able to find it over the web now that you know what to look for. There will be more than one key, each separated by the literal string "<cr>".

    HTH!

    ~raffaele

  • i am java coder but i need to develop an app for my win ce6 device in .net.

    i tired this code, but i do something wrong.

    i only made a new project and inserted this code. i was able to compile and depoly to my device.

    here my output:

    Modul laden: RasConn.exe

    Modul laden: coredll.dll.0409.MUI

    Modul laden: MZFC0960.dll

    Modul laden: ddraw.dll

    Modul laden: fpcrt.dll

    Modul laden: ole32.dll

    Modul laden: rpcrt4.dll

    Modul laden: lpcrt.dll

    Modul laden: coredll.dll

    Das Programm "[0xB72007E] RasConn.exe" wurde mit Code -1 (0xffffffff) beendet.

    can u help me?

    here you can see why i need this:

    http://www.meizume.com/m8-applications/9705-net-application-establish-gprs-connection.html

    there is a firmware bug on my mobile device. so i am not able to make a connection with mobilkom austria.

    so i need an application to do this.

    regards,

    Markus

  • Hi Markus, I'm sorry but didn't understand precisely the issue. I imagine you know that the sample above is native language, not for .NET Compact Framework (so you should use Win32 templates). Also, make sure you're targeting the right platform: Wiindows *Mobile* is different from Windows *CE* in terms of GPRS connectivity (the Connection Manager is available only on Mobile). Consider also opening a Service Request at Microsoft Technical Support: this may be an option, before the issue becomes too urgent. Viceversa, i.e. if not urgent, then we may also try continuing offline - just contact me thru http://blogs.msdn.com/raffael/contact.aspx.

    HTH!

    ~raffaele

  • native means that i can use a Win32 template and can run on win ce6 too?

    I know that i have to use RAS and not CM.

    I used a ppc template.

Page 1 of 2 (22 items) 12