Partilhar via


GPS Poll Driver Sample

I mention here that the information about the GPSID poll driver is now included in WinCE 6.  If you are an OEM implementing a GPS driver on CE6 and you're not natively spitting out NMEA but would have to generate NMEA only for GPSID to parse, I'd highly recommend that you check out this information.

To help get you started, I'm including sample code that shows how to implement a poll driver.  As I call out at the top of the file, this is a simple illustrative sample only.  In this case I hard-code a starting position and change it slightly every time that the driver is called in order to simulate movement.  As you can see it's not rocket science to plug into the GPSID interface, the tricky portion is controlling your actual GPS device of course!

<PollService.cpp>

// WARNING: THIS CODE HAS NO SECURITY CHECKS, HAS NOT BEEN PROPERLY TESTED, AND IS FOR ILLUSTRATIVE
// PURPOSES ONLY.  IT MUST NOT BE SHIPPED AS-IS

// Simple server to test GPSID and POLL based drivers.
// This is an extremely primitive service, just enough to test basic GPSID
// interactions.  The hard-core dev tests for POLL drivers are in ..\whiteBox\PollDriver.cpp

/* This is the sample registry to use this service
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\GPS Intermediate Driver\Drivers\Poll]
"InterfaceType" = "Poll"
"CommPort" = "GPP0:"

[HKEY_LOCAL_MACHINE\Services\GPSPollService]
   "Dll"="PollService"
   "Order"=dword:15
   "Keep"=dword:1
   "Index"=dword:0
   "Prefix"="GPP"

*/

#include <windows.h>
#include <service.h>
#include <gpsapi.h>
#include <gpsDev.h>

DWORD g_dwServiceState = SERVICE_STATE_ON;

// Position we return is based on this data, though we'll change it slightly over time
// to make things more interesting.
static GPS_POSITION gpsData = {1, sizeof(GPS_POSITION),  0x0003ffff, 0, {2001, 3, 0, 1, 21, 10, 54, 0}, 4723.7722, -12011.9324, (FLOAT)0.06, (FLOAT)76.77,  18.1,
                          (FLOAT)364.5, (FLOAT)-18.3, GPS_FIX_QUALITY_GPS, GPS_FIX_3D, GPS_FIX_SELECTION_AUTO, (FLOAT) 2.2,
                          (FLOAT)1.2, (FLOAT)1.8, 7, { 0x05, 0x11, 0x1e, 0x18, 0x19, 0x06, 0x0a, 0, 0, 0, 0, 0 }, 8,
                            { 0x1e, 0x06, 0x0a, 0x18, 0x05, 0x19, 0x11, 0x07, 0, 0, 0, 0 }, // rgdwSatellitesInViewPRNs
                            { 0x40, 0x36, 0x2e, 0x2d, 0x2d, 0x0e, 0x0e, 0x05, 0, 0, 0, 0 }, // rgdwSatellitesInViewElevation
                            { 0x0ea,0x126,0x083,0x036,0x0b6,0x12d,0x0e7,0x142,0,0,0,0 }, // rgdwSatellitesInViewAzimuth
                            { 0x02f,0x02b,0x02f,0x02e,0x02e,0x028,0x02a,0x02a,0,0,0,0} // rgdwSatellitesInViewSignalToNoiseRatio
};

extern "C" DWORD GPP_Init (DWORD dwData) {
 return TRUE;
}

extern "C" BOOL GPP_Deinit(DWORD dwData) {
 return TRUE;
}

extern "C" DWORD GPP_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
 return TRUE;
}

extern "C" BOOL GPP_Close (DWORD dwData) {
 return TRUE;
}

extern "C" BOOL GPP_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
                              DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
                              PDWORD pdwActualOut)
{
 DWORD dwError = ERROR_INVALID_PARAMETER;
 // Control code sent to start a service.
 switch (dwCode) {
 case IOCTL_SERVICE_START:
     g_dwServiceState = SERVICE_STATE_ON;
 break;

 case IOCTL_SERVICE_STOP:
  g_dwServiceState = SERVICE_STATE_OFF;
 break;   
 
 case IOCTL_SERVICE_STATUS:
  *(DWORD *)pBufOut = g_dwServiceState;
  *pdwActualOut = sizeof(DWORD);
 break;

 // GPSID requests current location...
 case IOCTL_GPS_DRIVER_GET_LOCATION_V1:
  if (g_dwServiceState == SERVICE_STATE_ON) {
   ASSERT((pBufOut != NULL) && (dwLenOut == sizeof(GPS_POSITION)));
   gpsData.dblLatitude  += 0.04;
   gpsData.dblLongitude -= 0.05;
   memcpy(pBufOut,&gpsData,sizeof(gpsData));
   *pdwActualOut = sizeof(gpsData);
  }
  else {
   SetLastError(ERROR_SERVICE_NOT_ACTIVE);
   return FALSE;
  }
 break;

 default:
  SetLastError(ERROR_INVALID_PARAMETER);
  return FALSE;
 break;
 }

 return TRUE;
}

extern "C" BOOL WINAPI DllEntry( HANDLE hInstDll, DWORD fdwReason,
                 LPVOID lpvReserved) {
 return TRUE;
}

<PollService.def>

LIBRARY     POLLSERVICE

EXPORTS
    GPP_Init
    GPP_Deinit
    GPP_Open
    GPP_Close
    GPP_IOControl

[Author: John Spaith]

Comments

  • Anonymous
    December 07, 2006
    Hi John:could you envision an event-driven mechanism to drive the whole thing, maybe for the next Windows Mobile. For navigation type apps that happen to use the parsed api, doing polling underneath potentially just increases the latency, which can affect the customer experience negatively. The positioning on the map gets delayed, so you might get the friendly voice telling you to turn right just as you hit an intersection, instead of a bit before, that sort of thing. How about passing the hNewLocationData from the GPSOpenDevice into the driver underneath (via some new ioctl?) ?Best regards, Patrick
  • Anonymous
    December 07, 2006
    The comment has been removed
  • Anonymous
    December 08, 2006
    NMEA polling is similiar to pollDriver (just mechanism is different) so hopefully by the time data gets to app it's not so different.But with nmea polling from com port you probably are using the ReadIntervalTimeout and ReadTotalTimeoutConstant timeout value to throttle the actual polling, so if data has been coming in, you will return quicker than with having a timer on the outside and then doing the non-blocking IOCTL_GPS_DRIVER_GET_LOCATION_V1 call. So I would expect the nmea poll to have less delay than poll driver, or am I missing something?Note on the side, nave apps traditionally give a notice a long time before and then just about 50-100 yards before you need to make the turn, that's the one you don't want to come too late.I absolutely agree on the gps being quite demanding on the battery though, so increasing the pollling might not be too bad after all.
  • Anonymous
    January 02, 2007
    Patrick - for NMEA polling I actually call into the driver itself and block (since this is just how the serial drivers are, and they take the CommTimeouts settings), for poll-driver GPSID itself is the one throttling the calls.  Both calls for ReadFile() & the PollDriver IOCTL should be pretty fast, mainly limited by the underlying GPS driver itself.  The poll driver may actually end up being slightly faster because it doesn't have to parse out NMEA string, whereas the NMEA one will of course.No matter what, though, I'd think that the time delays between both shouldn't be too bad - no one has complained in actual practice yet about the NMEA one, though poll driver is new and hasn't had the tires kicked in by real use yet.John
  • Anonymous
    February 21, 2007
    Hi ,Could somebody please let me know how to call  AppA [console application exe]   from AppB ? [Both are windows CE apps]. Where I can find some sample code for that.?thanks in advance.Rajesh
  • Anonymous
    February 22, 2007
    Rajesh, please check out http://blogs.msdn.com/cenet/archive/2005/07/13/438424.aspx for an intro to interprocess communication on CE.  For future questions I'd recommend posting on a newsgroup since the interface (in my opinion) is easier to deal with, http://blogs.msdn.com/cenet/archive/2005/12/05/500181.aspx has a list of newsgroups I check dailyJohn
  • Anonymous
    March 23, 2007
    The comment has been removed
  • Anonymous
    April 11, 2007
    Is it possible to include this GPS intermediate driver in to the WinCE 5.0 manually? Can we make WinCE 5.0 support GPSID?
  • Anonymous
    April 12, 2007
    I'm afraid GPSID on CE 5.0 isn't possible due to various legal/licensing type agreements with the way that we ship the code.  Sorry I don't have a better answer for you here.John
  • Anonymous
    April 12, 2007
    Kamal - to answer your question, I think you're running into the issue described here:http://blogs.msdn.com/cenet/archive/2006/02/10/windows-ce-gpsid-its-c-wrapper-and-device-emulator-interaction-issues.aspxApologies on very delayed response.  I'd recommend a newsgroup for questions like this, listed http://blogs.msdn.com/cenet/archive/2005/12/05/500181.aspx.John
  • Anonymous
    August 31, 2007
    Should this work in WM5 as well?
  • Anonymous
    September 20, 2007
    I'm afraid it won't work in WM5 or WM6.  Basically the way our WM release dates are staggered a bit differently than the general embededd, and it just happened that I had time to do this in CE6 but it was too late for WM*.  This absolutely will be present in WM7.